import { SmrtClassOptions } from '@happyvertical/smrt-core'; import { Asset } from './asset'; import { AssetAssociation } from './asset-association'; import { AssetAssociationCollection } from './asset-associations'; import { AssetCapabilityProvider, AssetExternalSourceRef, AssetExternalSyncResult, AssetNearbySearchInput, AssetProcessResult, AssetSearchResult, AssetVariantRequest, AssetVariantResult, AssetWorkflowInput, AssetWorkflowResult } from './asset-capabilities'; import { AssetExtractionStatus, AssetRole } from './asset-conventions'; import { AssetStore, AssetStoreOptions, ProviderOptions, StoreOptions } from './asset-store'; import { AssetCollection } from './assets'; /** * DB configuration accepted by the runtime — mirrors the shape * `SmrtCollection.create({ db })` already accepts. */ export type AssetRuntimeDb = NonNullable; /** * Options for constructing an `AssetRuntime` via `createAssetRuntime()`. */ export interface AssetRuntimeOptions { /** * Database used for `AssetCollection` and `AssetAssociationCollection`. * * Accepts anything `SmrtCollection.create({ db })` accepts — a string * URL, a config object, or a live `DatabaseInterface`. */ db: AssetRuntimeDb; /** * Storage provider for `AssetStore`. * * A string is treated as a local filesystem `basePath`; otherwise * forwarded to `@happyvertical/files`. */ storage: ProviderOptions; /** * Optional behavior for the underlying `AssetStore`. * * Use this to provide a storage resolver while keeping the convenience * runtime factory. */ storeOptions?: AssetStoreOptions; /** * Optional collection instance. If omitted, one is created from `db`. * Useful in tests or when the caller already has a configured * collection (e.g. from `ObjectRegistry`). */ collection?: AssetCollection; /** * Optional associations collection. If omitted, one is created from `db`. */ associations?: AssetAssociationCollection; /** * Optional asset capability providers. * * Providers let callers keep one app-facing asset runtime while * delegating processing, variant generation, search, external sync, or * workflow submission to local processors or external systems. */ capabilityProviders?: AssetCapabilityProvider[]; } /** * Structural shape of the runtime. Agents and serving helpers should * depend on `AssetRuntimeLike` rather than the concrete class so tests * can pass in a minimal object. */ export interface AssetRuntimeLike { readonly collection: AssetCollection; readonly associations: AssetAssociationCollection; readonly store: AssetStore; readonly capabilityProviders?: readonly AssetCapabilityProvider[]; /** Persist original bytes and their Asset record through the shared store. */ storeSourceAsset(name: string, data: Buffer, opts: StoreOptions): Promise; } /** * Options for `AssetRuntime.storeDerivedAsset()`. */ export interface StoreDerivedAssetOptions extends Omit { /** * Relationship role for the derivation link. * * Defaults to `ASSET_ROLES.DERIVATION_SOURCE` when `linkAssociation` * is true (the default). Set explicitly for roles like * `document_image` or `thumbnail` when a derivative has a more * specific semantic than "came from". */ role?: AssetRole | string; /** * If true (default), also create an `AssetAssociation` record with * `assetId=source.id`, `metaType=`, * `metaId=`, `role=` so the provenance link is * queryable independent of `sourceAssetId`. * * Set to `false` if you only want the column-level `sourceAssetId` * derivation link. */ linkAssociation?: boolean; /** * `metaType` string stored on the `AssetAssociation`. This describes * the *derivative* object (the target of `metaId`), not the source. * * Defaults to `'Asset'`. Callers whose derivatives are STI subclasses * — e.g. an `Image` produced from a PDF — should pass the subclass * name here so consumers can distinguish subtype derivatives from * plain assets. This matches the convention used by * `smrt-images`' `ImageDeriver.deriveWithAssociations()`. */ derivativeMetaType?: string; } /** * Options for `AssetRuntime.linkDerivation()`. */ export interface LinkDerivationOptions { role?: AssetRole | string; /** * `metaType` describing the derivative object (target of `metaId`). * See `StoreDerivedAssetOptions.derivativeMetaType`. */ derivativeMetaType?: string; } /** * Convenience runtime for `smrt-assets` callers. See the package * `CLAUDE.md` for the full "source vs derived" vocabulary. */ export declare class AssetRuntime implements AssetRuntimeLike { readonly collection: AssetCollection; readonly associations: AssetAssociationCollection; readonly store: AssetStore; readonly capabilityProviders: AssetCapabilityProvider[]; constructor(collection: AssetCollection, associations: AssetAssociationCollection, store: AssetStore, capabilityProviders?: AssetCapabilityProvider[]); registerCapabilityProvider(provider: AssetCapabilityProvider): this; private providersFor; processAsset(asset: Asset, input?: { variants?: AssetVariantRequest[]; metadata?: Record; }): Promise; ensureVariant(asset: Asset, request: AssetVariantRequest): Promise; searchNearbyAssets(input: Omit): Promise; syncExternalAsset(asset: Asset, input?: { externalId?: string | null; sourceRef?: AssetExternalSourceRef | null; metadata?: Record; }): Promise; submitAssetWorkflow(asset: Asset, input: Omit): Promise; /** * Create a new source asset with both a record and bytes on disk. * * This is the same as `AssetStore.store()`, but exposed on the runtime * so callers only need one handle. */ storeSourceAsset(name: string, data: Buffer, opts: StoreOptions): Promise; /** * Create a derivative of `source`, persist its bytes, and optionally * record a provenance association. * * The new asset's `sourceAssetId` always points at `source.id`. When * `linkAssociation` is true (the default), the runtime also writes * an `AssetAssociation` so queries by role (e.g. "all `document_image` * derivatives for this `source_document`") work without scanning * `source_asset_id` chains. */ storeDerivedAsset(source: Asset, name: string, data: Buffer, opts: StoreDerivedAssetOptions): Promise; /** * Record a provenance association between an existing source asset * and an existing derivative asset without touching bytes. */ linkDerivation(source: Asset, derivative: Asset, opts?: LinkDerivationOptions): Promise; /** * Update the standard extraction-status metadata on an asset's * `description` JSON sidecar. This is a thin convenience over the * convention in `asset-conventions.ts` — callers that store * metadata elsewhere can ignore it. * * **How existing descriptions are handled**: * - Empty / unset → fresh JSON object. * - Valid JSON object → merged into; existing keys preserved. * - Free-form prose or non-object JSON → preserved under the * reserved `text` key of the resulting object (e.g. * `{ text: "original prose", extractionStatus: "..." }`). No prose * is discarded. * * Callers that already use `text` for something else, or that need * an entirely separate metadata surface, should either round-trip * the JSON themselves or skip this helper — its only job is the * `extractionStatus` / `extractionError` / `extractedAt` triple. * * Error handling: when `status` transitions away from `failed` * without a new `extra.error`, the stale `extractionError` is * cleared so downstream consumers don't misread the current state. * When `status === 'succeeded'`, `extractedAt` is stamped to now * unless the caller provides one. */ setExtractionStatus(asset: Asset, status: AssetExtractionStatus, extra?: { error?: string; extractedAt?: Date; }): Promise; } /** * Factory — lazily creates a shared asset runtime from DB + storage * config. Initializes the store's filesystem adapter before returning. * * @example * ```ts * import { createAssetRuntime, ASSET_ROLES } from '@happyvertical/smrt-assets'; * * const runtime = await createAssetRuntime({ * db: { type: 'sqlite', url: 'app.db' }, * storage: { type: 's3', bucket: 'my-app' }, * }); * * const pdf = await runtime.storeSourceAsset('agenda.pdf', bytes, { * mimeType: 'application/pdf', * typeSlug: 'document', * }); * * await runtime.storeDerivedAsset(pdf, 'agenda-p1.png', pageBytes, { * mimeType: 'image/png', * typeSlug: 'image', * role: ASSET_ROLES.DOCUMENT_IMAGE, * }); * ``` */ export declare function createAssetRuntime(options: AssetRuntimeOptions): Promise; //# sourceMappingURL=asset-runtime.d.ts.map