@de-otio/chaoskb-client 0.2.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/dist/cli/agent-registry/config-merger.d.ts +28 -0
- package/dist/cli/agent-registry/config-merger.d.ts.map +1 -0
- package/dist/cli/agent-registry/config-merger.js +90 -0
- package/dist/cli/agent-registry/config-merger.js.map +1 -0
- package/dist/cli/agent-registry/detector.d.ts +7 -0
- package/dist/cli/agent-registry/detector.d.ts.map +1 -0
- package/dist/cli/agent-registry/detector.js +100 -0
- package/dist/cli/agent-registry/detector.js.map +1 -0
- package/dist/cli/agent-registry/index.d.ts +26 -0
- package/dist/cli/agent-registry/index.d.ts.map +1 -0
- package/dist/cli/agent-registry/index.js +77 -0
- package/dist/cli/agent-registry/index.js.map +1 -0
- package/dist/cli/agent-registry/path-validator.d.ts +11 -0
- package/dist/cli/agent-registry/path-validator.d.ts.map +1 -0
- package/dist/cli/agent-registry/path-validator.js +69 -0
- package/dist/cli/agent-registry/path-validator.js.map +1 -0
- package/dist/cli/agent-registry/registry.json +108 -0
- package/dist/cli/agent-registry/types.d.ts +29 -0
- package/dist/cli/agent-registry/types.d.ts.map +1 -0
- package/dist/cli/agent-registry/types.js +2 -0
- package/dist/cli/agent-registry/types.js.map +1 -0
- package/dist/cli/bootstrap-lock.d.ts +7 -0
- package/dist/cli/bootstrap-lock.d.ts.map +1 -0
- package/dist/cli/bootstrap-lock.js +62 -0
- package/dist/cli/bootstrap-lock.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +23 -0
- package/dist/cli/bootstrap.d.ts.map +1 -0
- package/dist/cli/bootstrap.js +438 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/commands/config.d.ts +13 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +244 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/devices.d.ts +21 -0
- package/dist/cli/commands/devices.d.ts.map +1 -0
- package/dist/cli/commands/devices.js +229 -0
- package/dist/cli/commands/devices.js.map +1 -0
- package/dist/cli/commands/export.d.ts +12 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +183 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/import.d.ts +26 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +311 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/kb.d.ts +39 -0
- package/dist/cli/commands/kb.d.ts.map +1 -0
- package/dist/cli/commands/kb.js +138 -0
- package/dist/cli/commands/kb.js.map +1 -0
- package/dist/cli/commands/project.d.ts +6 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +115 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/projects.d.ts +33 -0
- package/dist/cli/commands/projects.d.ts.map +1 -0
- package/dist/cli/commands/projects.js +189 -0
- package/dist/cli/commands/projects.js.map +1 -0
- package/dist/cli/commands/register.d.ts +8 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +146 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/rotate-key.d.ts +16 -0
- package/dist/cli/commands/rotate-key.d.ts.map +1 -0
- package/dist/cli/commands/rotate-key.js +197 -0
- package/dist/cli/commands/rotate-key.js.map +1 -0
- package/dist/cli/commands/setup-sync.d.ts +2 -0
- package/dist/cli/commands/setup-sync.d.ts.map +1 -0
- package/dist/cli/commands/setup-sync.js +165 -0
- package/dist/cli/commands/setup-sync.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +12 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +39 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/status.d.ts +5 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +96 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +4 -0
- package/dist/cli/commands/uninstall.d.ts.map +1 -0
- package/dist/cli/commands/uninstall.js +85 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/commands/unregister.d.ts +2 -0
- package/dist/cli/commands/unregister.d.ts.map +1 -0
- package/dist/cli/commands/unregister.js +46 -0
- package/dist/cli/commands/unregister.js.map +1 -0
- package/dist/cli/device-metadata.d.ts +15 -0
- package/dist/cli/device-metadata.d.ts.map +1 -0
- package/dist/cli/device-metadata.js +58 -0
- package/dist/cli/device-metadata.js.map +1 -0
- package/dist/cli/github.d.ts +38 -0
- package/dist/cli/github.d.ts.map +1 -0
- package/dist/cli/github.js +159 -0
- package/dist/cli/github.js.map +1 -0
- package/dist/cli/guide-hashes.json +13 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +226 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp-server.d.ts +205 -0
- package/dist/cli/mcp-server.d.ts.map +1 -0
- package/dist/cli/mcp-server.js +366 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/tools/kb-delete.d.ts +10 -0
- package/dist/cli/tools/kb-delete.d.ts.map +1 -0
- package/dist/cli/tools/kb-delete.js +28 -0
- package/dist/cli/tools/kb-delete.js.map +1 -0
- package/dist/cli/tools/kb-ingest.d.ts +13 -0
- package/dist/cli/tools/kb-ingest.d.ts.map +1 -0
- package/dist/cli/tools/kb-ingest.js +72 -0
- package/dist/cli/tools/kb-ingest.js.map +1 -0
- package/dist/cli/tools/kb-list.d.ts +20 -0
- package/dist/cli/tools/kb-list.d.ts.map +1 -0
- package/dist/cli/tools/kb-list.js +24 -0
- package/dist/cli/tools/kb-list.js.map +1 -0
- package/dist/cli/tools/kb-query-shared.d.ts +27 -0
- package/dist/cli/tools/kb-query-shared.d.ts.map +1 -0
- package/dist/cli/tools/kb-query-shared.js +28 -0
- package/dist/cli/tools/kb-query-shared.js.map +1 -0
- package/dist/cli/tools/kb-query.d.ts +20 -0
- package/dist/cli/tools/kb-query.d.ts.map +1 -0
- package/dist/cli/tools/kb-query.js +109 -0
- package/dist/cli/tools/kb-query.js.map +1 -0
- package/dist/cli/tools/kb-summary.d.ts +29 -0
- package/dist/cli/tools/kb-summary.d.ts.map +1 -0
- package/dist/cli/tools/kb-summary.js +89 -0
- package/dist/cli/tools/kb-summary.js.map +1 -0
- package/dist/cli/tools/kb-sync-status.d.ts +7 -0
- package/dist/cli/tools/kb-sync-status.d.ts.map +1 -0
- package/dist/cli/tools/kb-sync-status.js +48 -0
- package/dist/cli/tools/kb-sync-status.js.map +1 -0
- package/dist/crypto/aad.d.ts +8 -0
- package/dist/crypto/aad.d.ts.map +1 -0
- package/dist/crypto/aad.js +11 -0
- package/dist/crypto/aad.js.map +1 -0
- package/dist/crypto/aead.d.ts +21 -0
- package/dist/crypto/aead.d.ts.map +1 -0
- package/dist/crypto/aead.js +43 -0
- package/dist/crypto/aead.js.map +1 -0
- package/dist/crypto/argon2.d.ts +11 -0
- package/dist/crypto/argon2.d.ts.map +1 -0
- package/dist/crypto/argon2.js +33 -0
- package/dist/crypto/argon2.js.map +1 -0
- package/dist/crypto/blob-id.d.ts +6 -0
- package/dist/crypto/blob-id.d.ts.map +1 -0
- package/dist/crypto/blob-id.js +33 -0
- package/dist/crypto/blob-id.js.map +1 -0
- package/dist/crypto/canonical-json.d.ts +6 -0
- package/dist/crypto/canonical-json.d.ts.map +1 -0
- package/dist/crypto/canonical-json.js +88 -0
- package/dist/crypto/canonical-json.js.map +1 -0
- package/dist/crypto/commitment.d.ts +12 -0
- package/dist/crypto/commitment.d.ts.map +1 -0
- package/dist/crypto/commitment.js +37 -0
- package/dist/crypto/commitment.js.map +1 -0
- package/dist/crypto/encryption-service.d.ts +19 -0
- package/dist/crypto/encryption-service.d.ts.map +1 -0
- package/dist/crypto/encryption-service.js +38 -0
- package/dist/crypto/encryption-service.js.map +1 -0
- package/dist/crypto/envelope-cbor.d.ts +37 -0
- package/dist/crypto/envelope-cbor.d.ts.map +1 -0
- package/dist/crypto/envelope-cbor.js +124 -0
- package/dist/crypto/envelope-cbor.js.map +1 -0
- package/dist/crypto/envelope.d.ts +34 -0
- package/dist/crypto/envelope.d.ts.map +1 -0
- package/dist/crypto/envelope.js +160 -0
- package/dist/crypto/envelope.js.map +1 -0
- package/dist/crypto/hkdf.d.ts +16 -0
- package/dist/crypto/hkdf.d.ts.map +1 -0
- package/dist/crypto/hkdf.js +33 -0
- package/dist/crypto/hkdf.js.map +1 -0
- package/dist/crypto/index.d.ts +15 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +15 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/invite.d.ts +31 -0
- package/dist/crypto/invite.d.ts.map +1 -0
- package/dist/crypto/invite.js +137 -0
- package/dist/crypto/invite.js.map +1 -0
- package/dist/crypto/keyring.d.ts +37 -0
- package/dist/crypto/keyring.d.ts.map +1 -0
- package/dist/crypto/keyring.js +219 -0
- package/dist/crypto/keyring.js.map +1 -0
- package/dist/crypto/known-keys.d.ts +34 -0
- package/dist/crypto/known-keys.d.ts.map +1 -0
- package/dist/crypto/known-keys.js +106 -0
- package/dist/crypto/known-keys.js.map +1 -0
- package/dist/crypto/project-keys.d.ts +26 -0
- package/dist/crypto/project-keys.d.ts.map +1 -0
- package/dist/crypto/project-keys.js +69 -0
- package/dist/crypto/project-keys.js.map +1 -0
- package/dist/crypto/secure-buffer.d.ts +31 -0
- package/dist/crypto/secure-buffer.d.ts.map +1 -0
- package/dist/crypto/secure-buffer.js +61 -0
- package/dist/crypto/secure-buffer.js.map +1 -0
- package/dist/crypto/ssh-agent.d.ts +16 -0
- package/dist/crypto/ssh-agent.d.ts.map +1 -0
- package/dist/crypto/ssh-agent.js +225 -0
- package/dist/crypto/ssh-agent.js.map +1 -0
- package/dist/crypto/ssh-keys.d.ts +19 -0
- package/dist/crypto/ssh-keys.d.ts.map +1 -0
- package/dist/crypto/ssh-keys.js +121 -0
- package/dist/crypto/ssh-keys.js.map +1 -0
- package/dist/crypto/tiers/enhanced.d.ts +25 -0
- package/dist/crypto/tiers/enhanced.d.ts.map +1 -0
- package/dist/crypto/tiers/enhanced.js +56 -0
- package/dist/crypto/tiers/enhanced.js.map +1 -0
- package/dist/crypto/tiers/maximum.d.ts +19 -0
- package/dist/crypto/tiers/maximum.d.ts.map +1 -0
- package/dist/crypto/tiers/maximum.js +25 -0
- package/dist/crypto/tiers/maximum.js.map +1 -0
- package/dist/crypto/tiers/standard.d.ts +27 -0
- package/dist/crypto/tiers/standard.d.ts.map +1 -0
- package/dist/crypto/tiers/standard.js +147 -0
- package/dist/crypto/tiers/standard.js.map +1 -0
- package/dist/crypto/types.d.ts +169 -0
- package/dist/crypto/types.d.ts.map +1 -0
- package/dist/crypto/types.js +11 -0
- package/dist/crypto/types.js.map +1 -0
- package/dist/pipeline/chunker.d.ts +27 -0
- package/dist/pipeline/chunker.d.ts.map +1 -0
- package/dist/pipeline/chunker.js +96 -0
- package/dist/pipeline/chunker.js.map +1 -0
- package/dist/pipeline/content-pipeline.d.ts +24 -0
- package/dist/pipeline/content-pipeline.d.ts.map +1 -0
- package/dist/pipeline/content-pipeline.js +49 -0
- package/dist/pipeline/content-pipeline.js.map +1 -0
- package/dist/pipeline/embedder.d.ts +49 -0
- package/dist/pipeline/embedder.d.ts.map +1 -0
- package/dist/pipeline/embedder.js +195 -0
- package/dist/pipeline/embedder.js.map +1 -0
- package/dist/pipeline/extract.d.ts +17 -0
- package/dist/pipeline/extract.d.ts.map +1 -0
- package/dist/pipeline/extract.js +70 -0
- package/dist/pipeline/extract.js.map +1 -0
- package/dist/pipeline/fetch.d.ts +26 -0
- package/dist/pipeline/fetch.d.ts.map +1 -0
- package/dist/pipeline/fetch.js +91 -0
- package/dist/pipeline/fetch.js.map +1 -0
- package/dist/pipeline/index.d.ts +10 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +10 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/model-manager.d.ts +57 -0
- package/dist/pipeline/model-manager.d.ts.map +1 -0
- package/dist/pipeline/model-manager.js +234 -0
- package/dist/pipeline/model-manager.js.map +1 -0
- package/dist/pipeline/search.d.ts +37 -0
- package/dist/pipeline/search.d.ts.map +1 -0
- package/dist/pipeline/search.js +65 -0
- package/dist/pipeline/search.js.map +1 -0
- package/dist/pipeline/tokenizer.d.ts +29 -0
- package/dist/pipeline/tokenizer.d.ts.map +1 -0
- package/dist/pipeline/tokenizer.js +54 -0
- package/dist/pipeline/tokenizer.js.map +1 -0
- package/dist/pipeline/types.d.ts +86 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +2 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/pipeline/wordpiece-tokenizer.d.ts +60 -0
- package/dist/pipeline/wordpiece-tokenizer.d.ts.map +1 -0
- package/dist/pipeline/wordpiece-tokenizer.js +251 -0
- package/dist/pipeline/wordpiece-tokenizer.js.map +1 -0
- package/dist/storage/chunk-repo.d.ts +29 -0
- package/dist/storage/chunk-repo.d.ts.map +1 -0
- package/dist/storage/chunk-repo.js +115 -0
- package/dist/storage/chunk-repo.js.map +1 -0
- package/dist/storage/database-manager.d.ts +17 -0
- package/dist/storage/database-manager.d.ts.map +1 -0
- package/dist/storage/database-manager.js +100 -0
- package/dist/storage/database-manager.js.map +1 -0
- package/dist/storage/database.d.ts +10 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +34 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/embedding-index.d.ts +22 -0
- package/dist/storage/embedding-index.d.ts.map +1 -0
- package/dist/storage/embedding-index.js +78 -0
- package/dist/storage/embedding-index.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +10 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/kb-database.d.ts +11 -0
- package/dist/storage/kb-database.d.ts.map +1 -0
- package/dist/storage/kb-database.js +24 -0
- package/dist/storage/kb-database.js.map +1 -0
- package/dist/storage/schema.d.ts +6 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +122 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/source-repo.d.ts +20 -0
- package/dist/storage/source-repo.d.ts.map +1 -0
- package/dist/storage/source-repo.js +120 -0
- package/dist/storage/source-repo.js.map +1 -0
- package/dist/storage/sync-status-repo.d.ts +15 -0
- package/dist/storage/sync-status-repo.d.ts.map +1 -0
- package/dist/storage/sync-status-repo.js +40 -0
- package/dist/storage/sync-status-repo.js.map +1 -0
- package/dist/storage/types.d.ts +139 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +9 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/sync/canary.d.ts +14 -0
- package/dist/sync/canary.d.ts.map +1 -0
- package/dist/sync/canary.js +53 -0
- package/dist/sync/canary.js.map +1 -0
- package/dist/sync/full-sync.d.ts +16 -0
- package/dist/sync/full-sync.d.ts.map +1 -0
- package/dist/sync/full-sync.js +91 -0
- package/dist/sync/full-sync.js.map +1 -0
- package/dist/sync/http-client.d.ts +28 -0
- package/dist/sync/http-client.d.ts.map +1 -0
- package/dist/sync/http-client.js +90 -0
- package/dist/sync/http-client.js.map +1 -0
- package/dist/sync/incremental-sync.d.ts +17 -0
- package/dist/sync/incremental-sync.d.ts.map +1 -0
- package/dist/sync/incremental-sync.js +155 -0
- package/dist/sync/incremental-sync.js.map +1 -0
- package/dist/sync/index.d.ts +12 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +12 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/quota.d.ts +17 -0
- package/dist/sync/quota.d.ts.map +1 -0
- package/dist/sync/quota.js +48 -0
- package/dist/sync/quota.js.map +1 -0
- package/dist/sync/sequence.d.ts +21 -0
- package/dist/sync/sequence.d.ts.map +1 -0
- package/dist/sync/sequence.js +49 -0
- package/dist/sync/sequence.js.map +1 -0
- package/dist/sync/ssh-signer.d.ts +59 -0
- package/dist/sync/ssh-signer.d.ts.map +1 -0
- package/dist/sync/ssh-signer.js +241 -0
- package/dist/sync/ssh-signer.js.map +1 -0
- package/dist/sync/sync-service.d.ts +48 -0
- package/dist/sync/sync-service.d.ts.map +1 -0
- package/dist/sync/sync-service.js +116 -0
- package/dist/sync/sync-service.js.map +1 -0
- package/dist/sync/types.d.ts +106 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +2 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/sync/upload-queue.d.ts +40 -0
- package/dist/sync/upload-queue.d.ts.map +1 -0
- package/dist/sync/upload-queue.js +148 -0
- package/dist/sync/upload-queue.js.map +1 -0
- package/dist/sync/verification.d.ts +17 -0
- package/dist/sync/verification.d.ts.map +1 -0
- package/dist/sync/verification.js +25 -0
- package/dist/sync/verification.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +16 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-signer.js","sourceRoot":"","sources":["../../sync/ssh-signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ISyncService, SyncConfig, SyncResult, QuotaInfo } from './types.js';
|
|
2
|
+
import type { IDatabase } from '../storage/types.js';
|
|
3
|
+
import type { IEncryptionService, DerivedKeySet } from '../crypto/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Main sync service that orchestrates all sync operations.
|
|
6
|
+
*
|
|
7
|
+
* Manages SSH signing, HTTP communication, upload queueing,
|
|
8
|
+
* and sync state persistence.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SyncService implements ISyncService {
|
|
11
|
+
private readonly httpClient;
|
|
12
|
+
private readonly uploadQueue;
|
|
13
|
+
private readonly storage;
|
|
14
|
+
private readonly encryptionService;
|
|
15
|
+
private readonly keys;
|
|
16
|
+
private state;
|
|
17
|
+
constructor(config: SyncConfig, storage: IDatabase, encryptionService: IEncryptionService, keys: DerivedKeySet);
|
|
18
|
+
/**
|
|
19
|
+
* Run incremental sync — download changes since last successful sync.
|
|
20
|
+
*/
|
|
21
|
+
incrementalSync(): Promise<SyncResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Run full sync — download all blobs from the server.
|
|
24
|
+
*/
|
|
25
|
+
fullSync(): Promise<SyncResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Enqueue a blob for upload to the server.
|
|
28
|
+
*/
|
|
29
|
+
upload(blobId: string, data: Uint8Array): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Get current quota usage from the server.
|
|
32
|
+
*
|
|
33
|
+
* Fetches quota info from the blob count endpoint, which includes
|
|
34
|
+
* quota headers in its response.
|
|
35
|
+
*/
|
|
36
|
+
getQuota(): Promise<QuotaInfo>;
|
|
37
|
+
/**
|
|
38
|
+
* Write and verify a canary blob to confirm encryption keys work.
|
|
39
|
+
*/
|
|
40
|
+
verifyCanary(): Promise<boolean>;
|
|
41
|
+
/**
|
|
42
|
+
* Verify that the local blob count matches the server.
|
|
43
|
+
*/
|
|
44
|
+
verifyCount(localCount: number): Promise<boolean>;
|
|
45
|
+
private loadState;
|
|
46
|
+
private saveState;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=sync-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-service.d.ts","sourceRoot":"","sources":["../../sync/sync-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EAEV,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAa5E;;;;;GAKG;AACH,qBAAa,WAAY,YAAW,YAAY;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IACvD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,KAAK,CAAY;gBAGvB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,SAAS,EAClB,iBAAiB,EAAE,kBAAkB,EACrC,IAAI,EAAE,aAAa;IAWrB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,UAAU,CAAC;IAkB5C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAMrC;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,SAAS,CAAC;IAepC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAItC;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKvD,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,SAAS;CAOlB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import { SSHSigner } from './ssh-signer.js';
|
|
5
|
+
import { SyncHttpClient } from './http-client.js';
|
|
6
|
+
import { UploadQueue } from './upload-queue.js';
|
|
7
|
+
import { incrementalSync } from './incremental-sync.js';
|
|
8
|
+
import { fullSync } from './full-sync.js';
|
|
9
|
+
import { verifyCanary } from './canary.js';
|
|
10
|
+
import { verifyBlobCount } from './verification.js';
|
|
11
|
+
const CHAOSKB_DIR = join(homedir(), '.chaoskb');
|
|
12
|
+
const SYNC_STATE_PATH = join(CHAOSKB_DIR, 'sync-state.json');
|
|
13
|
+
const UPLOAD_QUEUE_PATH = join(CHAOSKB_DIR, 'upload-queue.json');
|
|
14
|
+
/**
|
|
15
|
+
* Main sync service that orchestrates all sync operations.
|
|
16
|
+
*
|
|
17
|
+
* Manages SSH signing, HTTP communication, upload queueing,
|
|
18
|
+
* and sync state persistence.
|
|
19
|
+
*/
|
|
20
|
+
export class SyncService {
|
|
21
|
+
httpClient;
|
|
22
|
+
uploadQueue;
|
|
23
|
+
storage;
|
|
24
|
+
encryptionService;
|
|
25
|
+
keys;
|
|
26
|
+
state;
|
|
27
|
+
constructor(config, storage, encryptionService, keys) {
|
|
28
|
+
const signer = new SSHSigner(config.sshKeyPath);
|
|
29
|
+
this.httpClient = new SyncHttpClient(config, signer);
|
|
30
|
+
this.uploadQueue = new UploadQueue(this.httpClient, UPLOAD_QUEUE_PATH);
|
|
31
|
+
this.storage = storage;
|
|
32
|
+
this.encryptionService = encryptionService;
|
|
33
|
+
this.keys = keys;
|
|
34
|
+
this.state = this.loadState();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Run incremental sync — download changes since last successful sync.
|
|
38
|
+
*/
|
|
39
|
+
async incrementalSync() {
|
|
40
|
+
const result = await incrementalSync(this.httpClient, this.storage, this.state.lastSyncTimestamp);
|
|
41
|
+
if (result.success) {
|
|
42
|
+
this.state.lastSyncTimestamp = new Date().toISOString();
|
|
43
|
+
this.saveState();
|
|
44
|
+
}
|
|
45
|
+
// Process any pending uploads after downloading
|
|
46
|
+
await this.uploadQueue.processQueue();
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Run full sync — download all blobs from the server.
|
|
51
|
+
*/
|
|
52
|
+
async fullSync() {
|
|
53
|
+
const result = await fullSync(this.httpClient, this.storage, this.state);
|
|
54
|
+
this.saveState();
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Enqueue a blob for upload to the server.
|
|
59
|
+
*/
|
|
60
|
+
async upload(blobId, data) {
|
|
61
|
+
await this.uploadQueue.enqueue(blobId, data);
|
|
62
|
+
// Attempt immediate upload
|
|
63
|
+
await this.uploadQueue.processQueue();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get current quota usage from the server.
|
|
67
|
+
*
|
|
68
|
+
* Fetches quota info from the blob count endpoint, which includes
|
|
69
|
+
* quota headers in its response.
|
|
70
|
+
*/
|
|
71
|
+
async getQuota() {
|
|
72
|
+
const response = await this.httpClient.get('/v1/blobs/count');
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
throw new Error(`Failed to get quota: HTTP ${response.status}`);
|
|
75
|
+
}
|
|
76
|
+
const data = (await response.json());
|
|
77
|
+
if (data.quota) {
|
|
78
|
+
return data.quota;
|
|
79
|
+
}
|
|
80
|
+
// Fallback: no quota info available
|
|
81
|
+
return { used: 0, limit: 0, percentage: 0 };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Write and verify a canary blob to confirm encryption keys work.
|
|
85
|
+
*/
|
|
86
|
+
async verifyCanary() {
|
|
87
|
+
return verifyCanary(this.httpClient, this.encryptionService, this.keys);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Verify that the local blob count matches the server.
|
|
91
|
+
*/
|
|
92
|
+
async verifyCount(localCount) {
|
|
93
|
+
const result = await verifyBlobCount(this.httpClient, localCount);
|
|
94
|
+
return result.match;
|
|
95
|
+
}
|
|
96
|
+
loadState() {
|
|
97
|
+
try {
|
|
98
|
+
if (existsSync(SYNC_STATE_PATH)) {
|
|
99
|
+
const raw = readFileSync(SYNC_STATE_PATH, 'utf-8');
|
|
100
|
+
return JSON.parse(raw);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Corrupted state file — start fresh
|
|
105
|
+
}
|
|
106
|
+
return { fullSyncInProgress: false };
|
|
107
|
+
}
|
|
108
|
+
saveState() {
|
|
109
|
+
const dir = dirname(SYNC_STATE_PATH);
|
|
110
|
+
if (!existsSync(dir)) {
|
|
111
|
+
mkdirSync(dir, { recursive: true });
|
|
112
|
+
}
|
|
113
|
+
writeFileSync(SYNC_STATE_PATH, JSON.stringify(this.state, null, 2), 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=sync-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-service.js","sourceRoot":"","sources":["../../sync/sync-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** Sync configuration */
|
|
2
|
+
export interface SyncConfig {
|
|
3
|
+
/** Server endpoint URL (must be HTTPS) */
|
|
4
|
+
endpoint: string;
|
|
5
|
+
/** Path to SSH private key (fallback if ssh-agent unavailable) */
|
|
6
|
+
sshKeyPath?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Sync state persisted between syncs */
|
|
9
|
+
export interface SyncState {
|
|
10
|
+
/** ISO 8601 timestamp of last successful sync */
|
|
11
|
+
lastSyncTimestamp?: string;
|
|
12
|
+
/** Cursor for resuming paginated full sync */
|
|
13
|
+
fullSyncCursor?: string;
|
|
14
|
+
/** Whether a full sync is in progress */
|
|
15
|
+
fullSyncInProgress: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** Result of a sync operation */
|
|
18
|
+
export interface SyncResult {
|
|
19
|
+
/** Number of new blobs downloaded */
|
|
20
|
+
newBlobs: number;
|
|
21
|
+
/** Number of updated blobs */
|
|
22
|
+
updatedBlobs: number;
|
|
23
|
+
/** Number of tombstones processed */
|
|
24
|
+
deletedBlobs: number;
|
|
25
|
+
/** Conflicts detected and resolved */
|
|
26
|
+
conflicts: SyncConflict[];
|
|
27
|
+
/** Errors encountered (non-fatal) */
|
|
28
|
+
errors: SyncError[];
|
|
29
|
+
/** Whether sync completed successfully */
|
|
30
|
+
success: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** A sync conflict that was detected and resolved */
|
|
33
|
+
export interface SyncConflict {
|
|
34
|
+
blobId: string;
|
|
35
|
+
/** How the conflict was resolved */
|
|
36
|
+
resolution: 'local_wins' | 'remote_wins' | 'keep_both';
|
|
37
|
+
/** Why a conflict was detected */
|
|
38
|
+
reason: string;
|
|
39
|
+
/** Timestamp of local version */
|
|
40
|
+
localTimestamp?: string;
|
|
41
|
+
/** Timestamp of remote version */
|
|
42
|
+
remoteTimestamp?: string;
|
|
43
|
+
}
|
|
44
|
+
/** Sync error */
|
|
45
|
+
export interface SyncError {
|
|
46
|
+
blobId?: string;
|
|
47
|
+
message: string;
|
|
48
|
+
code: string;
|
|
49
|
+
retryable: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Blob metadata from server */
|
|
52
|
+
export interface BlobMetadata {
|
|
53
|
+
id: string;
|
|
54
|
+
size: number;
|
|
55
|
+
ts: string;
|
|
56
|
+
}
|
|
57
|
+
/** Tombstone from server */
|
|
58
|
+
export interface Tombstone {
|
|
59
|
+
id: string;
|
|
60
|
+
deletedAt: string;
|
|
61
|
+
}
|
|
62
|
+
/** Server list response */
|
|
63
|
+
export interface BlobListResponse {
|
|
64
|
+
blobs: BlobMetadata[];
|
|
65
|
+
tombstones: Tombstone[];
|
|
66
|
+
}
|
|
67
|
+
/** Upload queue item */
|
|
68
|
+
export interface UploadQueueItem {
|
|
69
|
+
blobId: string;
|
|
70
|
+
data: Uint8Array;
|
|
71
|
+
retryCount: number;
|
|
72
|
+
lastAttempt?: string;
|
|
73
|
+
error?: string;
|
|
74
|
+
}
|
|
75
|
+
/** Quota information from server */
|
|
76
|
+
export interface QuotaInfo {
|
|
77
|
+
/** Bytes used */
|
|
78
|
+
used: number;
|
|
79
|
+
/** Bytes allowed */
|
|
80
|
+
limit: number;
|
|
81
|
+
/** Usage percentage (0-100) */
|
|
82
|
+
percentage: number;
|
|
83
|
+
}
|
|
84
|
+
/** Sync service interface */
|
|
85
|
+
export interface ISyncService {
|
|
86
|
+
/** Run incremental sync (download changes since last sync) */
|
|
87
|
+
incrementalSync(): Promise<SyncResult>;
|
|
88
|
+
/** Run full sync (download all blobs) */
|
|
89
|
+
fullSync(): Promise<SyncResult>;
|
|
90
|
+
/** Upload a blob to the server */
|
|
91
|
+
upload(blobId: string, data: Uint8Array): Promise<void>;
|
|
92
|
+
/** Get current quota usage */
|
|
93
|
+
getQuota(): Promise<QuotaInfo>;
|
|
94
|
+
/** Write and verify canary blob */
|
|
95
|
+
verifyCanary(): Promise<boolean>;
|
|
96
|
+
/** Verify blob count matches server */
|
|
97
|
+
verifyCount(localCount: number): Promise<boolean>;
|
|
98
|
+
}
|
|
99
|
+
/** HTTP client for server communication */
|
|
100
|
+
export interface ISyncHttpClient {
|
|
101
|
+
get(path: string): Promise<Response>;
|
|
102
|
+
put(path: string, body: Uint8Array): Promise<Response>;
|
|
103
|
+
delete(path: string): Promise<Response>;
|
|
104
|
+
post(path: string, body?: Uint8Array): Promise<Response>;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../sync/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../sync/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ISyncHttpClient, UploadQueueItem } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Persistent upload queue for async blob uploads.
|
|
4
|
+
*
|
|
5
|
+
* Items are serialized to a JSON file on disk so uploads survive
|
|
6
|
+
* process restarts. Each mutation (enqueue, dequeue, retry increment)
|
|
7
|
+
* persists the queue immediately.
|
|
8
|
+
*/
|
|
9
|
+
export declare class UploadQueue {
|
|
10
|
+
private readonly client;
|
|
11
|
+
private readonly queuePath;
|
|
12
|
+
private items;
|
|
13
|
+
constructor(client: ISyncHttpClient, queuePath: string);
|
|
14
|
+
/**
|
|
15
|
+
* Add a blob to the upload queue and persist to disk.
|
|
16
|
+
*/
|
|
17
|
+
enqueue(blobId: string, data: Uint8Array): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Process all queued uploads. Returns counts of successes and failures.
|
|
20
|
+
*
|
|
21
|
+
* - On 409 (already exists): remove from queue (idempotent success).
|
|
22
|
+
* - On 413 (quota exceeded): stop processing entirely.
|
|
23
|
+
* - On other failure: increment retry count; mark sync_failed after MAX_RETRIES.
|
|
24
|
+
*/
|
|
25
|
+
processQueue(): Promise<{
|
|
26
|
+
uploaded: number;
|
|
27
|
+
failed: number;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Number of items still in the queue (including failed).
|
|
31
|
+
*/
|
|
32
|
+
getPendingCount(): number;
|
|
33
|
+
/**
|
|
34
|
+
* Get all items in the queue (for inspection/testing).
|
|
35
|
+
*/
|
|
36
|
+
getItems(): readonly UploadQueueItem[];
|
|
37
|
+
private loadFromDisk;
|
|
38
|
+
private saveToDisk;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=upload-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-queue.d.ts","sourceRoot":"","sources":["../../sync/upload-queue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAenE;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,KAAK,CAAoB;gBAErB,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM;IAOtD;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9D;;;;;;OAMG;IACG,YAAY,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA2DnE;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACH,QAAQ,IAAI,SAAS,eAAe,EAAE;IAItC,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,UAAU;CAcnB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
/** Maximum number of retries before marking an item as permanently failed. */
|
|
4
|
+
const MAX_RETRIES = 5;
|
|
5
|
+
/**
|
|
6
|
+
* Persistent upload queue for async blob uploads.
|
|
7
|
+
*
|
|
8
|
+
* Items are serialized to a JSON file on disk so uploads survive
|
|
9
|
+
* process restarts. Each mutation (enqueue, dequeue, retry increment)
|
|
10
|
+
* persists the queue immediately.
|
|
11
|
+
*/
|
|
12
|
+
export class UploadQueue {
|
|
13
|
+
client;
|
|
14
|
+
queuePath;
|
|
15
|
+
items;
|
|
16
|
+
constructor(client, queuePath) {
|
|
17
|
+
this.client = client;
|
|
18
|
+
this.queuePath = queuePath;
|
|
19
|
+
this.items = [];
|
|
20
|
+
this.loadFromDisk();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Add a blob to the upload queue and persist to disk.
|
|
24
|
+
*/
|
|
25
|
+
async enqueue(blobId, data) {
|
|
26
|
+
// Replace existing entry for the same blobId
|
|
27
|
+
this.items = this.items.filter((item) => item.blobId !== blobId);
|
|
28
|
+
this.items.push({
|
|
29
|
+
blobId,
|
|
30
|
+
data: new Uint8Array(data),
|
|
31
|
+
retryCount: 0,
|
|
32
|
+
});
|
|
33
|
+
this.saveToDisk();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Process all queued uploads. Returns counts of successes and failures.
|
|
37
|
+
*
|
|
38
|
+
* - On 409 (already exists): remove from queue (idempotent success).
|
|
39
|
+
* - On 413 (quota exceeded): stop processing entirely.
|
|
40
|
+
* - On other failure: increment retry count; mark sync_failed after MAX_RETRIES.
|
|
41
|
+
*/
|
|
42
|
+
async processQueue() {
|
|
43
|
+
let uploaded = 0;
|
|
44
|
+
let failed = 0;
|
|
45
|
+
const remaining = [];
|
|
46
|
+
for (const item of this.items) {
|
|
47
|
+
if (item.retryCount >= MAX_RETRIES) {
|
|
48
|
+
// Already exceeded max retries — mark as failed and skip
|
|
49
|
+
failed++;
|
|
50
|
+
remaining.push({ ...item, error: 'Max retries exceeded' });
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const response = await this.client.put(`/v1/blobs/${item.blobId}`, item.data);
|
|
55
|
+
if (response.ok || response.status === 201) {
|
|
56
|
+
// Success — do not keep in queue
|
|
57
|
+
uploaded++;
|
|
58
|
+
}
|
|
59
|
+
else if (response.status === 409) {
|
|
60
|
+
// Already exists — idempotent success
|
|
61
|
+
uploaded++;
|
|
62
|
+
}
|
|
63
|
+
else if (response.status === 413) {
|
|
64
|
+
// Quota exceeded — stop processing, keep this and remaining items
|
|
65
|
+
remaining.push(item);
|
|
66
|
+
// Push all unprocessed items
|
|
67
|
+
const currentIndex = this.items.indexOf(item);
|
|
68
|
+
for (let i = currentIndex + 1; i < this.items.length; i++) {
|
|
69
|
+
remaining.push(this.items[i]);
|
|
70
|
+
}
|
|
71
|
+
this.items = remaining;
|
|
72
|
+
this.saveToDisk();
|
|
73
|
+
return { uploaded, failed };
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Other failure — retry later
|
|
77
|
+
failed++;
|
|
78
|
+
remaining.push({
|
|
79
|
+
...item,
|
|
80
|
+
retryCount: item.retryCount + 1,
|
|
81
|
+
lastAttempt: new Date().toISOString(),
|
|
82
|
+
error: `HTTP ${response.status}`,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
failed++;
|
|
88
|
+
remaining.push({
|
|
89
|
+
...item,
|
|
90
|
+
retryCount: item.retryCount + 1,
|
|
91
|
+
lastAttempt: new Date().toISOString(),
|
|
92
|
+
error: error instanceof Error ? error.message : String(error),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
this.items = remaining;
|
|
97
|
+
this.saveToDisk();
|
|
98
|
+
return { uploaded, failed };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Number of items still in the queue (including failed).
|
|
102
|
+
*/
|
|
103
|
+
getPendingCount() {
|
|
104
|
+
return this.items.length;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get all items in the queue (for inspection/testing).
|
|
108
|
+
*/
|
|
109
|
+
getItems() {
|
|
110
|
+
return this.items;
|
|
111
|
+
}
|
|
112
|
+
loadFromDisk() {
|
|
113
|
+
try {
|
|
114
|
+
if (!existsSync(this.queuePath)) {
|
|
115
|
+
this.items = [];
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const raw = readFileSync(this.queuePath, 'utf-8');
|
|
119
|
+
const serialized = JSON.parse(raw);
|
|
120
|
+
this.items = serialized.map((s) => ({
|
|
121
|
+
blobId: s.blobId,
|
|
122
|
+
data: Uint8Array.from(Buffer.from(s.data, 'base64')),
|
|
123
|
+
retryCount: s.retryCount,
|
|
124
|
+
lastAttempt: s.lastAttempt,
|
|
125
|
+
error: s.error,
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Corrupted or missing file — start fresh
|
|
130
|
+
this.items = [];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
saveToDisk() {
|
|
134
|
+
const dir = dirname(this.queuePath);
|
|
135
|
+
if (!existsSync(dir)) {
|
|
136
|
+
mkdirSync(dir, { recursive: true });
|
|
137
|
+
}
|
|
138
|
+
const serialized = this.items.map((item) => ({
|
|
139
|
+
blobId: item.blobId,
|
|
140
|
+
data: Buffer.from(item.data).toString('base64'),
|
|
141
|
+
retryCount: item.retryCount,
|
|
142
|
+
lastAttempt: item.lastAttempt,
|
|
143
|
+
error: item.error,
|
|
144
|
+
}));
|
|
145
|
+
writeFileSync(this.queuePath, JSON.stringify(serialized, null, 2), 'utf-8');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=upload-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-queue.js","sourceRoot":"","sources":["../../sync/upload-queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ISyncHttpClient } from './types.js';
|
|
2
|
+
/** Result of a blob count verification. */
|
|
3
|
+
export interface VerifyCountResult {
|
|
4
|
+
match: boolean;
|
|
5
|
+
localCount: number;
|
|
6
|
+
serverCount: number;
|
|
7
|
+
/** If mismatch exceeds 10%, suggests a full sync. */
|
|
8
|
+
suggestFullSync?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Verify that the local blob count matches the server count.
|
|
12
|
+
*
|
|
13
|
+
* If the mismatch exceeds 10%, the result includes a suggestion
|
|
14
|
+
* to run a full sync.
|
|
15
|
+
*/
|
|
16
|
+
export declare function verifyBlobCount(client: ISyncHttpClient, localCount: number): Promise<VerifyCountResult>;
|
|
17
|
+
//# sourceMappingURL=verification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../../sync/verification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC,CAoB5B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify that the local blob count matches the server count.
|
|
3
|
+
*
|
|
4
|
+
* If the mismatch exceeds 10%, the result includes a suggestion
|
|
5
|
+
* to run a full sync.
|
|
6
|
+
*/
|
|
7
|
+
export async function verifyBlobCount(client, localCount) {
|
|
8
|
+
const response = await client.get('/v1/blobs/count');
|
|
9
|
+
if (!response.ok) {
|
|
10
|
+
throw new Error(`Failed to get server blob count: HTTP ${response.status}`);
|
|
11
|
+
}
|
|
12
|
+
const data = (await response.json());
|
|
13
|
+
const serverCount = data.count;
|
|
14
|
+
const match = localCount === serverCount;
|
|
15
|
+
let suggestFullSync;
|
|
16
|
+
if (!match) {
|
|
17
|
+
const maxCount = Math.max(localCount, serverCount);
|
|
18
|
+
const diff = Math.abs(localCount - serverCount);
|
|
19
|
+
if (maxCount > 0 && diff / maxCount > 0.1) {
|
|
20
|
+
suggestFullSync = true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return { match, localCount, serverCount, suggestFullSync };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=verification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../../sync/verification.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAuB,EACvB,UAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACrD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yCAAyC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAsB,CAAC;IAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;IAC/B,MAAM,KAAK,GAAG,UAAU,KAAK,WAAW,CAAC;IAEzC,IAAI,eAAoC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC;QAChD,IAAI,QAAQ,GAAG,CAAC,IAAI,IAAI,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC;YAC1C,eAAe,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../vitest.config.ts"],"names":[],"mappings":";AAEA,wBAaG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
export default defineConfig({
|
|
3
|
+
test: {
|
|
4
|
+
include: ['**/__tests__/**/*.test.ts'],
|
|
5
|
+
coverage: {
|
|
6
|
+
provider: 'v8',
|
|
7
|
+
reporter: ['text', 'lcov'],
|
|
8
|
+
thresholds: {
|
|
9
|
+
lines: 80,
|
|
10
|
+
branches: 80,
|
|
11
|
+
functions: 80,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=vitest.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.config.js","sourceRoot":"","sources":["../vitest.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE;QACJ,OAAO,EAAE,CAAC,2BAA2B,CAAC;QACtC,QAAQ,EAAE;YACR,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;YAC1B,UAAU,EAAE;gBACV,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,EAAE;gBACZ,SAAS,EAAE,EAAE;aACd;SACF;KACF;CACF,CAAC,CAAC"}
|