import type { EncryptedFS } from 'encryptedfs'; import type { ContextTimed, ContextTimedInput } from '@matrixai/contexts'; import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; import type { RPCClient } from '@matrixai/rpc'; import type { ResourceAcquire } from '@matrixai/resources'; import type { CommitLog, FileSystemReadable, FileSystemWritable, VaultAction, VaultId, VaultIdEncoded, VaultName, VaultRef } from './types.js'; import type { NodeId, NodeIdEncoded } from '../ids/types.js'; import type KeyRing from '../keys/KeyRing.js'; import type NodeManager from '../nodes/NodeManager.js'; import type { AgentClientManifest } from '../nodes/agent/callers/index.js'; import type agentClientManifest from '../nodes/agent/callers/index.js'; import Logger from '@matrixai/logger'; import { createDestroyStartStop } from '@matrixai/async-init'; import { RWLockWriter } from '@matrixai/async-locks'; type RemoteInfo = { remoteNode: NodeIdEncoded; remoteVault: VaultIdEncoded; }; interface VaultInternal extends createDestroyStartStop.CreateDestroyStartStop { } declare class VaultInternal { /** * Creates a VaultInternal. * If no state already exists then a new state for the vault is initialized. * If state already exists then this just creates the `VaultInternal` * instance for managing that state. */ static createVaultInternal({ vaultId, vaultName, db, vaultsDbPath, keyRing, efs, fresh, logger, }: { vaultId: VaultId; vaultName?: VaultName; db: DB; vaultsDbPath: LevelPath; keyRing: KeyRing; efs: EncryptedFS; fresh?: boolean; logger?: Logger; }, tran?: DBTransaction, ctx?: Partial): Promise; /** * Will create a new vault by cloning the vault from a remote node. */ static cloneVaultInternal({ targetNodeId, targetVaultNameOrId, vaultId, db, vaultsDbPath, efs, keyRing, nodeManager, logger, }: { targetNodeId: NodeId; targetVaultNameOrId: VaultId | VaultName; vaultId: VaultId; db: DB; vaultsDbPath: LevelPath; efs: EncryptedFS; keyRing: KeyRing; nodeManager: NodeManager; logger?: Logger; }, tran?: DBTransaction, ctx?: Partial): Promise; static dirtyKey: string; static remoteKey: string; static nameKey: string; readonly vaultId: VaultId; readonly vaultIdEncoded: string; readonly vaultDataDir: string; readonly vaultGitDir: string; protected logger: Logger; protected db: DB; protected vaultsDbPath: LevelPath; protected vaultMetadataDbPath: LevelPath; protected keyRing: KeyRing; protected vaultsNamesPath: LevelPath; protected efs: EncryptedFS; protected efsVault: EncryptedFS; protected lock: RWLockWriter; getLock(): RWLockWriter; constructor({ vaultId, db, vaultsDbPath, keyRing, efs, logger, }: { vaultId: VaultId; db: DB; vaultsDbPath: LevelPath; keyRing: KeyRing; efs: EncryptedFS; logger: Logger; }); /** * @param fresh Should the state be cleared before starting? * @param vaultName Name of the vault. Only used when creating a new vault. * @param tran * @param ctx */ start({ vaultName, fresh, }?: { vaultName?: VaultName; fresh?: boolean; }, tran?: DBTransaction, ctx?: ContextTimed): Promise; /** * We use a protected start method to avoid the `async-init` lifecycle * deadlocking when doing the recursive call to create a DBTransaction. */ protected start_({ vaultName, fresh, }: { vaultName?: VaultName; fresh: boolean; }, tran: DBTransaction, ctx?: Partial): Promise; stop(): Promise; destroy(tran?: DBTransaction): Promise; /** * We use a protected destroy method to avoid the `async-init` lifecycle * deadlocking when doing the recursive call to create a DBTransaction. */ protected destroy_(tran: DBTransaction): Promise; log(ref?: string | VaultRef, limit?: number): Promise>; /** * Checks out the vault repository to specific commit ID or special tags. * This changes the working directory and updates the HEAD reference. */ version(ref?: string | VaultRef): Promise; /** * With context handler for using a vault in a read-only context. */ readF(f: (fs: FileSystemReadable) => Promise): Promise; /** * With context handler for using a vault in a read-only context for a * generator. */ readG(g: (fs: FileSystemReadable) => AsyncGenerator): AsyncGenerator; /** * With context handler for using a vault in a writable context. */ writeF(f: (fs: FileSystemWritable) => Promise, tran?: DBTransaction, ctx?: Partial): Promise; /** * With context handler for using a vault in a writable context for a generator. */ writeG(g: (fs: FileSystemWritable) => AsyncGenerator, tran?: DBTransaction, ctx?: Partial): AsyncGenerator; /** * Acquire a read-only lock on this vault. */ acquireRead(): ResourceAcquire; /** * Acquire a read-write lock on this vault. */ acquireWrite(tran: DBTransaction | undefined, ctx: ContextTimed): ResourceAcquire; /** * Pulls changes to a vault from the vault's default remote. If `pullNodeId` * and `pullVaultNameOrId` it uses that for the remote instead. */ pullVault({ nodeManager, pullNodeId, pullVaultNameOrId, }: { nodeManager: NodeManager; pullNodeId?: NodeId; pullVaultNameOrId?: VaultId | VaultName; }, tran?: DBTransaction, ctx?: Partial): Promise; /** * Sets up the vault metadata. * Creates a `dirty` boolean in the database to track dirty state of the vault. * Also adds the vault's name to the database. */ protected setupMeta({ vaultName }: { vaultName?: VaultName; }, tran: DBTransaction): Promise; /** * Does an idempotent initialization of the git repository for the vault. * If the vault is in a dirty state then we clean up the working directory * or any history not part of the canonical branch. */ protected setupGit(tran: DBTransaction, ctx: ContextTimed): Promise; /** * Creates a request arrow function that implements an API that `isomorphic-git` * expects to use when making a HTTP request. It makes RPC calls to * `vaultsGitInfoGet` for the ref advertisement phase and `vaultsGitPackGet` * for the git pack phase. * * `vaultsGitInfoGet` wraps a call to `gitHttp.advertiseRefGenerator` and * `vaultsGitPackGet` to `gitHttp.generatePackRequest`. * * ``` * ┌─────────┐ ┌───────────────────────────┐ * │ │ │ │ * ┌──────────────────────┐ │ RPC │ │ │ * │ │ │ │ │ *advertiseRefGenerator() │ * │ ├────────┼─────────┼────▶ │ * │ vault.request() │ │ │ │ │ * │ │ │ │ └────┬──────────────────────┘ * │ ├──┐ │ │ │ * │ │ │ │ │ ┌────▼──────────────────────┐ * └──────────────────────┘ │ │ │ │ │ * │ │ │ │ *referenceListGenerator() │ * │ │ │ │ │ * │ │ │ └───────────────────────────┘ * │ │ │ * │ │ │ ┌───────────────────────────┐ * └─────┼─────────┼────┤ │ * │ │ │ *generatePackRequest() │ * │ │ │ │ * │ │ └────┬──────────────────────┘ * └─────────┘ │ * ┌────▼──────────────────────┐ * │ │ * │ *generatePackData() │ * │ │ * └───────────────────────────┘ * * ``` */ protected request(client: RPCClient, vaultNameOrId: VaultId | VaultName, vaultAction: VaultAction): Promise; /** * Creates a commit while moving the canonicalBranch reference to that new commit. * If the commit creates a branch from the canonical history. Then the new commit * becomes the new canonical history and the old history is removed from the old * canonical head to the branch point. This is to maintain the strict * non-branching linear history. */ protected createCommit(ctx: ContextTimed): Promise; /** * Cleans the git working directory by checking out the canonical branch. * This will remove any un-committed changes since any untracked or modified * files outside a commit is dirty state. Dirty state should only happen if * the usual commit procedure was interrupted ungracefully. */ protected cleanWorkingDirectory(ctx: ContextTimed): Promise; /** * This will walk the current canonical branch history and delete any objects * that are not a part of it. This is costly since it will compare the walked * tree with all existing objects. */ protected garbageCollectGitObjectsGlobal(ctx: ContextTimed): Promise; /** * This will walk from the `startId` to the `StopId` deleting objects as it * goes. This is smarter since it only walks over the old history and not * everything. */ protected garbageCollectGitObjectsLocal(startId: string, stopId: string, ctx: ContextTimed): Promise; } export default VaultInternal; export type { RemoteInfo };