import type { CapabilityResult, Cleanup, TransferProgress, } from "./contracts.ts"; /** * Deep opt-in contracts for browser file and origin-storage capabilities. * * These contracts intentionally expose no File, Blob, FileSystemHandle, * IDBDatabase, IDBTransaction, Cache, Request or Response. A selected project * copies and narrows only the ports that its product actually owns. */ declare const byteCountBrand: unique symbol; declare const localFileRefBrand: unique symbol; declare const fileVerificationReceiptBrand: unique symbol; declare const filePolicyKeyBrand: unique symbol; declare const filePolicyIntentionBrand: unique symbol; declare const browserManagedCapabilityReceiptBrand: unique symbol; declare const authorizedDownloadCapabilityBrand: unique symbol; declare const authorizedDownloadCapabilityReceiptBrand: unique symbol; declare const objectIdBrand: unique symbol; declare const objectGenerationBrand: unique symbol; export type ByteCount = number & { readonly [byteCountBrand]: "ByteCount"; }; export type LocalFileRef = string & { readonly [localFileRefBrand]: "LocalFileRef"; }; export type FileVerificationReceipt = string & { readonly [fileVerificationReceiptBrand]: "FileVerificationReceipt"; }; export type FilePolicyKey = string & { readonly [filePolicyKeyBrand]: "FilePolicyKey"; }; export type FilePolicyIntention = string & { readonly [filePolicyIntentionBrand]: "FilePolicyIntention"; }; /** * Composition-issued capability selector. Implementations must resolve the * exact registered object identity, not merely an equal string pair. */ export type FilePolicyReference = Readonly<{ policyKey: FilePolicyKey; intention: FilePolicyIntention; }>; export type BrowserManagedDownloadCapabilityReceipt = string & { readonly [browserManagedCapabilityReceiptBrand]: "BrowserManagedDownloadCapabilityReceipt"; }; export type AuthorizedDownloadCapabilityReceipt = string & { readonly [authorizedDownloadCapabilityReceiptBrand]: "AuthorizedDownloadCapabilityReceipt"; }; /** * GET-only provider-issued handle. The corresponding URL, signed query and * headers stay inside the selected transfer adapter's in-memory identity * vault; a feature cannot replace them or supply its own digest. */ export type AuthorizedDownloadCapability = Readonly<{ capabilityReceipt: AuthorizedDownloadCapabilityReceipt; method: "GET"; binding: Readonly<{ kind: "DOWNLOAD"; resourceId: string; }>; mediaType: string; byteLength: ByteCount; maxBytes: ByteCount; expectedSha256: string; expiresAtEpochMs: number; readonly [authorizedDownloadCapabilityBrand]: "AuthorizedDownloadCapability"; }>; export type DurableObjectId = string & { readonly [objectIdBrand]: "DurableObjectId"; }; export type ObjectGeneration = number & { readonly [objectGenerationBrand]: "ObjectGeneration"; }; export type PersistableDataClass = | "PUBLIC" | "INTERNAL" | "PERSONAL" | "CONFIDENTIAL"; export type FileSelectionSource = | "NATIVE_INPUT" | "SYSTEM_PICKER" | "DROP"; export type FileAcceptRule = Readonly<{ mediaType: string; extensions: ReadonlyArray; }>; export type FileSelectionPolicy = Readonly<{ policyId: string; purpose: string; classification: PersistableDataClass; multiple: boolean; maxCount: number; maxFileBytes: ByteCount; maxTotalBytes: ByteCount; allowEmpty: boolean; accept: ReadonlyArray; }>; export type FileSelectionLimitReduction = Readonly<{ maxCount?: number; maxFileBytes?: ByteCount; maxTotalBytes?: ByteCount; }>; export type FileCandidate = Readonly<{ ref: LocalFileRef; displayName: string; sizeBytes: ByteCount; reportedMediaType: string | null; lastModifiedEpochMs: number | null; source: FileSelectionSource; }>; export type FileSelectionOutcome = | Readonly<{ kind: "SELECTED"; files: ReadonlyArray; }> | Readonly<{ kind: "DISMISSED" }>; export type FilePickerSupport = Readonly<{ nativeInput: true; systemOpenPicker: boolean; systemSavePicker: boolean; }>; export interface FilePickerPort { readonly support: FilePickerSupport; select(input: { policy: FilePolicyReference; limits?: FileSelectionLimitReduction; signal?: AbortSignal; }): Promise>; release(ref: LocalFileRef): void; } export type FileSignatureResult = | "MATCHED" | "MISMATCHED" | "UNKNOWN"; export type FileBytePattern = Readonly<{ offset: ByteCount; bytes: ReadonlyArray; mask?: ReadonlyArray; }>; export type FileSignatureRule = Readonly<{ mediaType: string; extensions: ReadonlyArray; patterns: ReadonlyArray; }>; export type FileInspectionPolicy = Readonly<{ policyId: string; maxInspectionBytes: ByteCount; acceptedSignatures: ReadonlyArray; }>; export type FileInspection = Readonly<{ byteLength: ByteCount; reportedMediaType: string | null; detectedMediaType: string | null; normalizedExtension: string | null; signature: FileSignatureResult; verificationReceipt: FileVerificationReceipt | null; }>; export type FileByteSource = Readonly<{ byteLength: ByteCount | null; stream( signal: AbortSignal, ): AsyncIterable>; }>; export interface FileContentPort { inspect(input: { ref: LocalFileRef; policy: FilePolicyReference; maxInspectionBytes?: ByteCount; signal: AbortSignal; }): Promise>; readRange(input: { ref: LocalFileRef; offset: ByteCount; length: ByteCount; signal: AbortSignal; }): Promise>; openSource(input: { ref: LocalFileRef; signal: AbortSignal; }): Promise>; release(ref: LocalFileRef): void; } export type PreviewLease = Readonly<{ url: string; mediaType: string; release: Cleanup; }>; /** * Presentation-local capability. The implementation owns object URL creation * and must revoke each lease on replacement, load failure and unmount. */ export interface TransientPreviewPort { create(input: { ref: LocalFileRef; verificationReceipt: FileVerificationReceipt; policy: FilePolicyReference; maxPreviewBytes?: ByteCount; signal: AbortSignal; }): Promise>; dispose(): void; } /** * Feature/backend workflow example, not a browser capability dependency. * Copy it only when the backend owns authorization, resumable-session expiry, * integrity verification, content inspection and quarantine promotion. */ export type ExampleUploadSession = Readonly<{ sessionId: string; partSizeBytes: ByteCount; maxConcurrency: number; expiresAt: string; checksumAlgorithm: "SHA-256"; }>; export type ExampleUploadPartReceipt = Readonly<{ partNumber: number; acceptedBytes: ByteCount; checksumSha256: string; }>; export type ExampleQuarantinedUpload = Readonly<{ resourceId: string; state: "QUARANTINED"; }>; export interface ExampleQuarantinedUploadPort { create(input: { purpose: string; byteLength: ByteCount; detectedMediaType: string; signal: AbortSignal; }): Promise>; uploadPart(input: { sessionId: string; partNumber: number; offset: ByteCount; bytes: Uint8Array; checksumSha256: string; idempotencyKey: string; signal: AbortSignal; }): Promise>; complete(input: { sessionId: string; parts: ReadonlyArray; signal: AbortSignal; }): Promise>; abort( sessionId: string, signal?: AbortSignal, ): Promise>; } export type DownloadSource = | Readonly<{ kind: "BROWSER_MANAGED_RESOURCE"; resourceId: string; capabilityReceipt: BrowserManagedDownloadCapabilityReceipt; }> | Readonly<{ kind: "AUTHORIZED_STREAM_RESOURCE"; resourceId: string; capability: AuthorizedDownloadCapability; }> | Readonly<{ kind: "GENERATED"; bytes: FileByteSource; expectedSha256?: string; }>; export type DownloadStrategy = | "BROWSER_MANAGED" | "PROMPT_AND_STREAM" | "BOUNDED_OBJECT_URL"; export type DownloadOutcome = | Readonly<{ kind: "BROWSER_HANDOFF"; transferId: string; }> | Readonly<{ kind: "SAVED"; transferId: string; bytesWritten: ByteCount; integrity: "VERIFIED" | "NOT_PROVIDED"; }> | Readonly<{ kind: "DISMISSED" }>; export interface DownloadDeliveryPort { deliver(input: { policy: FilePolicyReference; source: DownloadSource; suggestedFileName: string; maxTransferBytes?: ByteCount; maxBufferedBytes?: ByteCount; signal: AbortSignal; onProgress(progress: TransferProgress): void; }): Promise>; } export type BrowserManagedDownloadCapability = Readonly<{ capabilityReceipt: BrowserManagedDownloadCapabilityReceipt; href: string; resourceId: string; mediaType: string; safeExtension: string; maxBytes: ByteCount; expectedSha256?: string; expiresAtEpochMs: number; }>; export interface BrowserManagedDownloadCapabilityResolver { resolve(input: Readonly<{ resourceId: string; capabilityReceipt: BrowserManagedDownloadCapabilityReceipt; }>): CapabilityResult; } export type RegisteredPreviewPolicy = Readonly<{ allowedMediaTypes: ReadonlyArray; maxPreviewBytes: ByteCount; }>; export type RegisteredDownloadPolicy = Readonly<{ strategy: DownloadStrategy; mediaType: string; safeExtension: string; maxTransferBytes: ByteCount; maxBufferedBytes: ByteCount; integrity: "OPTIONAL" | "REQUIRED"; }>; /** * Dataset policy belongs at composition. Feature and presentation callers * receive only the reference plus optional reductions. */ export type BrowserFilePolicyProfile = Readonly<{ reference: FilePolicyReference; selection?: FileSelectionPolicy; inspection?: FileInspectionPolicy; preview?: RegisteredPreviewPolicy; download?: RegisteredDownloadPolicy; }>; export type BrowserPersistencePolicy = Readonly<{ owner: string; namespace: string; classification: PersistableDataClass; authority: "SERVER" | "LOCAL_FIRST" | "RECONSTRUCTABLE"; accountScope: "ORIGIN_SHARED" | "OPAQUE_PARTITION"; retention: | Readonly<{ kind: "SESSION" }> | Readonly<{ kind: "TTL"; maxAgeMs: number }> | Readonly<{ kind: "UNTIL_SYNCED" }> | Readonly<{ kind: "EXPLICIT_DELETE" }>; softBudgetBytes: ByteCount; hardBudgetBytes: ByteCount; evictionPriority: "RECONSTRUCTABLE" | "SYNCED_COPY" | "USER_AUTHORED"; logoutAction: | "KEEP_ORIGIN_SHARED" | "PURGE_PARTITION" | "EXPORT_THEN_PURGE"; accountDeletionAction: "KEEP_ORIGIN_SHARED" | "PURGE_PARTITION"; pressureAction: "EVICT_RECONSTRUCTABLE" | "RETAIN"; unavailableFallback: "ONLINE_ONLY" | "READ_ONLY" | "EXPORT_REQUIRED"; }>; export type OfflineStoreStatus = | Readonly<{ kind: "READY"; persistence: "BEST_EFFORT" | "PERSISTENT"; }> | Readonly<{ kind: "READ_ONLY"; reason: "FUTURE_SCHEMA" | "QUOTA" | "RECOVERY"; }> | Readonly<{ kind: "ONLINE_ONLY"; reason: "UNAVAILABLE" | "MIGRATION_FAILED"; }> | Readonly<{ kind: "UPGRADE_BLOCKED"; targetVersion: number; }> | Readonly<{ kind: "CLOSED"; reason: "VERSION_CHANGE" | "FORCED" | "DISPOSED"; }>; export type OfflineStoreLifecycleEvent = | Readonly<{ kind: "STATUS_CHANGED"; status: OfflineStoreStatus }> | Readonly<{ kind: "MIGRATION_PROGRESS"; migrationId: string; processedCount: number; remainingEstimate: number | null; }>; export type StoredRecord = Readonly<{ id: string; revision: number; payloadVersion: number; createdAtEpochMs: number; updatedAtEpochMs: number; expiresAtEpochMs: number | null; value: T; }>; export type RevisionGuard = | Readonly<{ kind: "ANY" }> | Readonly<{ kind: "MUST_NOT_EXIST" }> | Readonly<{ kind: "MATCH"; revision: number }>; export type StructuredOfflineMutation = | Readonly<{ kind: "PUT"; id: string; value: T; payloadVersion: number; expiresAtEpochMs: number | null; revision: RevisionGuard; }> | Readonly<{ kind: "DELETE"; id: string; revision: RevisionGuard; }>; export type OfflineCommitReceipt = Readonly<{ commitId: string; revisions: Readonly>; replayed: boolean; }>; export type OfflinePage = Readonly<{ records: ReadonlyArray>; nextCursor: string | null; }>; /** * Copy this as a feature-specific repository. Do not expose a generic * transaction callback, object-store name, index name or schema version. */ export interface StructuredOfflineStore { open(input: { partitionKey: string; signal?: AbortSignal; onLifecycle(event: OfflineStoreLifecycleEvent): void; }): Promise>; read( id: string, signal?: AbortSignal, ): Promise | null>>; page(input: { cursor?: string; limit: number; includeExpired?: boolean; signal?: AbortSignal; }): Promise>>; commit(input: { idempotencyKey: string; mutations: ReadonlyArray>; signal?: AbortSignal; }): Promise>; clearPartition(input: { reason: "LOGOUT" | "ACCOUNT_DELETION" | "USER_REQUEST"; signal?: AbortSignal; }): Promise>; status(): OfflineStoreStatus; close(): void; } export type MigrationProgress = Readonly<{ migrationId: string; state: "PENDING" | "RUNNING" | "COMPLETED" | "FAILED"; processedCount: number; remainingEstimate: number | null; }>; export interface OfflineStoreMaintenancePort { resumeDataMigration(input: { migrationId: string; maxRecords: number; timeBudgetMs: number; signal?: AbortSignal; }): Promise>; purgeExpired(input: { maxRecords: number; nowEpochMs: number; signal?: AbortSignal; }): Promise>>; } export type StorageEstimate = Readonly<{ usageBytes: number | null; quotaBytes: number | null; persisted: boolean | null; pressure: "UNKNOWN" | "NORMAL" | "PRESSURE" | "CRITICAL"; }>; export interface StorageDurabilityPort { inspect(signal?: AbortSignal): Promise>; requestPersistence(input: { reason: "PROTECT_UNSYNCED_USER_DATA"; userInitiated: true; signal?: AbortSignal; }): Promise>; } export type DurableObjectDataClass = | "RECONSTRUCTABLE" | "USER_CREATED_PRIVATE"; export type DurableObjectIntegrity = Readonly<{ algorithm: "SHA-256-TREE-V1"; rootDigest: string; chunkSizeBytes: ByteCount; }>; export type DurableObjectDescriptor = Readonly<{ id: DurableObjectId; generation: ObjectGeneration; byteLength: ByteCount; mediaType: string | null; integrity: DurableObjectIntegrity; dataClass: DurableObjectDataClass; retention: | Readonly<{ kind: "EXPLICIT_DELETE" }> | Readonly<{ kind: "EXPIRES"; expiresAt: string }>; }>; export type DurableObjectRead = Readonly<{ descriptor: DurableObjectDescriptor; chunks: AsyncIterable>; }>; export interface DurableObjectStorePort { capabilities(signal?: AbortSignal): Promise< CapabilityResult< Readonly<{ backend: "OPFS" | "INDEXEDDB_BLOB" | "NONE"; persistence: "BEST_EFFORT" | "PERSISTENT"; maxObjectBytes: ByteCount; }> > >; put(input: { id: DurableObjectId; expectedGeneration: ObjectGeneration | null; source: AsyncIterable>; declaredByteLength: ByteCount; mediaType: string | null; dataClass: DurableObjectDataClass; retention: DurableObjectDescriptor["retention"]; signal: AbortSignal; onProgress(progress: TransferProgress): void; }): Promise>; open( id: DurableObjectId, signal?: AbortSignal, ): Promise>; remove(input: { id: DurableObjectId; expectedGeneration: ObjectGeneration; signal?: AbortSignal; }): Promise>; } export type ObjectStoreRecoverySummary = Readonly<{ resumedCount: number; purgedCount: number; quarantinedCount: number; nextCursor: string | null; }>; export interface DurableObjectMaintenancePort { reconcile(input: { timeBudgetMs: number; maxEntries: number; cursor?: string; signal?: AbortSignal; }): Promise>; } export type PublicAssetEntry = Readonly<{ url: string; byteLength: ByteCount; mediaType: string; integritySha256: string; requestCredentials: "OMIT"; dataClass: "PUBLIC"; }>; export type PublicCacheLookup = | Readonly<{ kind: "HIT"; releaseId: string; entry: PublicAssetEntry; }> | Readonly<{ kind: "MISS"; reason: | "NOT_FOUND" | "EXPIRED" | "NO_ACTIVE_RELEASE" | "POLICY_REJECTED"; }>; export type PublicCacheInspection = Readonly<{ activeReleaseId: string | null; previousReleaseId: string | null; candidateReleaseIds: ReadonlyArray; ownedBytes: number | null; }>; /** * Platform-local Cache Storage policy facade. Raw Request/Response/Cache * objects remain inside the adapter, and no application repository imports it. */ export interface PublicResponseCacheAdmin { stageRelease(input: { releaseId: string; manifestDigest: string; entries: ReadonlyArray; signal: AbortSignal; }): Promise>; activateRelease(input: { releaseId: string; manifestDigest: string; expectedPreviousReleaseId: string | null; signal?: AbortSignal; }): Promise>; lookup(input: { url: string; requestCredentials: "OMIT"; hasAuthorization: false; signal?: AbortSignal; }): Promise>; inspect(signal?: AbortSignal): Promise< CapabilityResult >; rollback(signal?: AbortSignal): Promise>; deleteOwned(input: { roles: ReadonlyArray<"CANDIDATE" | "PREVIOUS" | "RUNTIME_PUBLIC">; signal?: AbortSignal; }): Promise>>; } export type BrowserFileComposition = Readonly<{ picker: FilePickerPort; content: FileContentPort; previews: TransientPreviewPort; downloads: DownloadDeliveryPort; }>; export type StructuredOfflineStorageComposition = Readonly<{ store: StructuredOfflineStore; maintenance: OfflineStoreMaintenancePort; }>; export type StorageDurabilityComposition = Readonly<{ durability: StorageDurabilityPort; }>; export type DurableObjectStorageComposition = Readonly<{ store: DurableObjectStorePort; maintenance: DurableObjectMaintenancePort; }>; export type PublicResponseCacheComposition = Readonly<{ cache: PublicResponseCacheAdmin; }>; /** * Explicitly separate from BrowserFileComposition: installing file selection, * preview or download must never imply a resumable backend upload protocol. */ export type ExampleBackendUploadComposition = Readonly<{ upload: ExampleQuarantinedUploadPort; }>;