feat: initial implementation of content-addressed incremental backup engine
Rust-centric architecture with TypeScript facade following smartproxy/smartstorage pattern. Core engine in Rust (FastCDC chunking, SHA-256, gzip, AES-256-GCM + Argon2id, binary pack files, global index, snapshots, locking, verification, pruning, repair). TypeScript provides npm interface via @push.rocks/smartrust RustBridge IPC with Unix socket streaming for ingest/restore. All 14 integration tests pass.
This commit is contained in:
219
ts/interfaces.ts
Normal file
219
ts/interfaces.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
import type { ICommandDefinition } from '@push.rocks/smartrust';
|
||||
|
||||
// ==================== Repository Config ====================
|
||||
|
||||
export interface IRepositoryConfig {
|
||||
version: number;
|
||||
id: string;
|
||||
createdAt: string;
|
||||
chunking: IChunkingConfig;
|
||||
compression: string;
|
||||
encryption?: IEncryptionConfig;
|
||||
packTargetSize: number;
|
||||
}
|
||||
|
||||
export interface IChunkingConfig {
|
||||
algorithm: string;
|
||||
minSize: number;
|
||||
avgSize: number;
|
||||
maxSize: number;
|
||||
}
|
||||
|
||||
export interface IEncryptionConfig {
|
||||
algorithm: string;
|
||||
kdf: string;
|
||||
kdfParams: IKdfParams;
|
||||
}
|
||||
|
||||
export interface IKdfParams {
|
||||
memory: number;
|
||||
iterations: number;
|
||||
parallelism: number;
|
||||
}
|
||||
|
||||
// ==================== Snapshots ====================
|
||||
|
||||
export interface ISnapshot {
|
||||
id: string;
|
||||
version: number;
|
||||
createdAt: string;
|
||||
tags: Record<string, string>;
|
||||
originalSize: number;
|
||||
storedSize: number;
|
||||
chunkCount: number;
|
||||
newChunks: number;
|
||||
reusedChunks: number;
|
||||
items: ISnapshotItem[];
|
||||
}
|
||||
|
||||
export interface ISnapshotItem {
|
||||
name: string;
|
||||
type: string;
|
||||
size: number;
|
||||
chunks: string[];
|
||||
}
|
||||
|
||||
export interface ISnapshotFilter {
|
||||
tags?: Record<string, string>;
|
||||
after?: string;
|
||||
before?: string;
|
||||
}
|
||||
|
||||
// ==================== Ingest ====================
|
||||
|
||||
export interface IInitOptions {
|
||||
passphrase?: string;
|
||||
chunking?: Partial<IChunkingConfig>;
|
||||
packTargetSize?: number;
|
||||
}
|
||||
|
||||
export interface IOpenOptions {
|
||||
passphrase?: string;
|
||||
}
|
||||
|
||||
export interface IIngestOptions {
|
||||
tags?: Record<string, string>;
|
||||
items?: IIngestItemOptions[];
|
||||
}
|
||||
|
||||
export interface IIngestItemOptions {
|
||||
name: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export interface IIngestItem {
|
||||
stream: NodeJS.ReadableStream;
|
||||
name: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
// ==================== Restore ====================
|
||||
|
||||
export interface IRestoreOptions {
|
||||
item?: string;
|
||||
}
|
||||
|
||||
// ==================== Maintenance ====================
|
||||
|
||||
export interface IVerifyOptions {
|
||||
level?: 'quick' | 'standard' | 'full';
|
||||
}
|
||||
|
||||
export interface IVerifyResult {
|
||||
ok: boolean;
|
||||
errors: IVerifyError[];
|
||||
stats: {
|
||||
packsChecked: number;
|
||||
chunksChecked: number;
|
||||
snapshotsChecked: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IVerifyError {
|
||||
pack?: string;
|
||||
chunk?: string;
|
||||
snapshot?: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
export interface IRetentionPolicy {
|
||||
keepLast?: number;
|
||||
keepDays?: number;
|
||||
keepWeeks?: number;
|
||||
keepMonths?: number;
|
||||
}
|
||||
|
||||
export interface IPruneResult {
|
||||
removedSnapshots: number;
|
||||
removedPacks: number;
|
||||
freedBytes: number;
|
||||
dryRun: boolean;
|
||||
}
|
||||
|
||||
export interface IRepairResult {
|
||||
indexRebuilt: boolean;
|
||||
indexedChunks: number;
|
||||
staleLocksRemoved: number;
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
export interface IUnlockOptions {
|
||||
force?: boolean;
|
||||
}
|
||||
|
||||
// ==================== Events ====================
|
||||
|
||||
export interface IIngestProgress {
|
||||
operation: string;
|
||||
percentage: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface IIngestComplete {
|
||||
snapshotId: string;
|
||||
originalSize: number;
|
||||
storedSize: number;
|
||||
newChunks: number;
|
||||
reusedChunks: number;
|
||||
}
|
||||
|
||||
// ==================== IPC Command Map ====================
|
||||
|
||||
export type TContainerArchiveCommands = {
|
||||
init: ICommandDefinition<
|
||||
{ path: string; passphrase?: string },
|
||||
IRepositoryConfig
|
||||
>;
|
||||
open: ICommandDefinition<
|
||||
{ path: string; passphrase?: string },
|
||||
IRepositoryConfig
|
||||
>;
|
||||
close: ICommandDefinition<
|
||||
Record<string, never>,
|
||||
Record<string, never>
|
||||
>;
|
||||
ingest: ICommandDefinition<
|
||||
{
|
||||
socketPath: string;
|
||||
tags?: Record<string, string>;
|
||||
items?: IIngestItemOptions[];
|
||||
},
|
||||
{ snapshot: ISnapshot }
|
||||
>;
|
||||
restore: ICommandDefinition<
|
||||
{
|
||||
snapshotId: string;
|
||||
socketPath: string;
|
||||
item?: string;
|
||||
},
|
||||
Record<string, never>
|
||||
>;
|
||||
listSnapshots: ICommandDefinition<
|
||||
{ filter?: ISnapshotFilter },
|
||||
{ snapshots: ISnapshot[] }
|
||||
>;
|
||||
getSnapshot: ICommandDefinition<
|
||||
{ snapshotId: string },
|
||||
{ snapshot: ISnapshot }
|
||||
>;
|
||||
verify: ICommandDefinition<
|
||||
{ level: string },
|
||||
IVerifyResult
|
||||
>;
|
||||
repair: ICommandDefinition<
|
||||
Record<string, never>,
|
||||
IRepairResult
|
||||
>;
|
||||
prune: ICommandDefinition<
|
||||
{ retention: IRetentionPolicy; dryRun?: boolean },
|
||||
IPruneResult
|
||||
>;
|
||||
reindex: ICommandDefinition<
|
||||
Record<string, never>,
|
||||
{ indexedChunks: number }
|
||||
>;
|
||||
unlock: ICommandDefinition<
|
||||
{ force?: boolean },
|
||||
{ removedLocks: number }
|
||||
>;
|
||||
};
|
||||
Reference in New Issue
Block a user