/**
 * @fileoverview Public types for the DataCanvas primitive — column schemas,
 * table info, and option/result shapes for register/query/export/describe.
 * Engine-agnostic; DuckDB is the current implementation.
 * @module src/services/canvas/types
 */
/**
 * Column type tag used when an explicit schema is provided to
 * {@link IDataCanvasProvider.registerTable}. The DuckDB provider maps these
 * to native DuckDB types; future engines map to their nearest equivalents.
 */
export type ColumnType = 'VARCHAR' | 'INTEGER' | 'BIGINT' | 'DOUBLE' | 'BOOLEAN' | 'TIMESTAMP' | 'DATE' | 'JSON' | 'BLOB';
/** Single column declaration in an explicit table schema. */
export interface ColumnSchema {
    /** Column name. Validated against the canvas identifier rules. */
    name: string;
    /** Whether NULL values are permitted. Defaults to `true`. */
    nullable?: boolean;
    /** Column type tag. */
    type: ColumnType;
}
/** Object kind exposed by {@link TableInfo}. Views are read-only derived projections. */
export type CanvasObjectKind = 'table' | 'view';
/** Metadata returned by {@link CanvasInstance.describe}. */
export interface TableInfo {
    /** Approximate in-memory footprint in bytes (engine-specific estimate). */
    approxSizeBytes?: number;
    /** Resolved schema for the table or view. */
    columns: ColumnSchema[];
    /**
     * ISO 8601 wall-clock expiry for this table's per-table TTL. Present only
     * when the table was registered with a `ttlMs` option. When absent, the
     * table inherits the canvas lifecycle (no independent expiry).
     */
    expiresAt?: string;
    /** Whether this entry is a base table or a registered view. */
    kind: CanvasObjectKind;
    /** Canvas-local name. */
    name: string;
    /**
     * Row count. For views, this is materialized at describe time via `COUNT(*)`
     * — not free; treat as an approximation if the view is expensive.
     */
    rowCount: number;
}
/** Options for {@link CanvasInstance.registerTable}. */
export interface RegisterTableOptions {
    /**
     * Explicit schema. When omitted, the provider sniffs the first N rows
     * (default 100) to infer types, falling back to `VARCHAR` for ambiguous
     * columns. **Required** when `rows` is an `AsyncIterable` — the provider
     * cannot peek without consuming.
     */
    schema?: ColumnSchema[];
    /** Cancellation signal forwarded to the provider. */
    signal?: AbortSignal;
    /**
     * Per-table sliding TTL in milliseconds. When set, this table expires
     * independently of the canvas — the sliding window is extended on any read
     * or write against this specific table. The sweep loop drops the table and
     * clears its bookkeeping when it expires; the canvas itself is unaffected
     * unless its own expiry fires independently. When omitted, the table
     * inherits the canvas lifecycle (no independent expiry).
     */
    ttlMs?: number;
}
/** Result of a successful {@link CanvasInstance.registerTable} call. */
export interface RegisterTableResult {
    /** Column names in declaration order. */
    columns: string[];
    /** Number of rows ingested. */
    rowCount: number;
    /** Resolved (validated, quoted-safe) table name. */
    tableName: string;
}
/** Options for {@link CanvasInstance.query}. */
export interface QueryOptions {
    /**
     * When `true`, the SQL gate rejects any reference to system catalog
     * namespaces (`information_schema`, `pg_catalog`, `sqlite_master`,
     * `duckdb_<name>()` functions) before executing. Default `false`.
     *
     * Use on shared canvases where handle possession is the access boundary —
     * catalog namespaces let callers enumerate every staged handle and defeat
     * that model. Canvas-token servers that expose `describe()` to agents do
     * not need this; only servers that intentionally hide the full catalog should
     * opt in.
     */
    denySystemCatalogs?: boolean;
    /**
     * Number of rows to include in the immediate response. Defaults to
     * `rowLimit`. Use a smaller value (e.g. 50) when `registerAs` is set and
     * the caller only wants a sample.
     */
    preview?: number;
    /**
     * Persist the result set as a new canvas table. The returned `rows` is
     * still bounded by `preview`/`rowLimit`; the full result lives on-canvas
     * under this name. Throws `Conflict` if a table with this name already
     * exists.
     */
    registerAs?: string;
    /**
     * Hard cap on rows materialized into the response. Default 10_000. To keep
     * a full result set, use `registerAs` (canonical) rather than raising this.
     */
    rowLimit?: number;
    /** Cancellation signal — interrupts the underlying connection. */
    signal?: AbortSignal;
    /**
     * Per-table sliding TTL for the table materialized via `registerAs`.
     * Ignored when `registerAs` is not set. Semantics match
     * {@link RegisterTableOptions.ttlMs}.
     */
    ttlMs?: number;
}
/** Result of a successful {@link CanvasInstance.query} call. */
export interface QueryResult {
    /** Column names in projection order. */
    columns: string[];
    /**
     * Rows the query produced, up to `rowLimit`. When `truncated` is `true`,
     * this equals `rowLimit` and the full result set is larger — use `registerAs`
     * to materialize the full result. When `truncated` is absent or `false`, this
     * is the exact row count.
     */
    rowCount: number;
    /** Materialized rows (bounded by `preview`/`rowLimit`). */
    rows: Record<string, unknown>[];
    /** Set when `registerAs` was supplied. */
    tableName?: string;
    /**
     * `true` when the query produced more rows than `rowLimit` and the result was
     * capped. Use `registerAs` to materialize the full result set as a canvas
     * table for follow-up SQL.
     */
    truncated?: boolean;
}
/** Supported export formats. */
export type ExportFormat = 'csv' | 'parquet' | 'json';
/**
 * Discriminated export target. Path-targeted exports are sandboxed to
 * `CANVAS_EXPORT_PATH`; absolute paths and `..` traversal are rejected.
 */
export type ExportTarget = {
    format: ExportFormat;
    path: string;
} | {
    format: ExportFormat;
    stream: WritableStream<Uint8Array>;
};
/** Options for {@link CanvasInstance.export}. */
export interface ExportOptions {
    /** Cancellation signal. */
    signal?: AbortSignal;
}
/** Result of a successful {@link CanvasInstance.export} call. */
export interface ExportResult {
    /** Format that was written. */
    format: ExportFormat;
    /** Absolute path written, when the target was a path; undefined for streams. */
    path?: string;
    /** Rows written. */
    rowCount: number;
    /** Bytes written. */
    sizeBytes: number;
}
/** Options for {@link CanvasInstance.describe}. */
export interface DescribeOptions {
    /** When set, return only entries with this kind. */
    kind?: CanvasObjectKind;
    /** When set, return only the named table or view. */
    tableName?: string;
}
/** Options for {@link CanvasInstance.registerView}. */
export interface RegisterViewOptions {
    /**
     * When `true`, the SQL gate rejects catalog namespace references in the view
     * definition SQL. Same semantics as {@link QueryOptions.denySystemCatalogs}.
     * Default `false`.
     */
    denySystemCatalogs?: boolean;
    /** Cancellation signal forwarded to the provider. */
    signal?: AbortSignal;
}
/** Result of a successful {@link CanvasInstance.registerView} call. */
export interface RegisterViewResult {
    /** Column names in projection order. */
    columns: string[];
    /** Resolved (validated) view name. */
    viewName: string;
}
/** Options for {@link CanvasInstance.importFrom}. */
export interface ImportFromOptions {
    /** Target-side name. Defaults to the source table name. */
    asName?: string;
    /** Cancellation signal forwarded to the provider. */
    signal?: AbortSignal;
}
/** Options for {@link DataCanvas.acquire}. */
export interface AcquireOptions {
    /** Cancellation signal for the acquire/init handshake. */
    signal?: AbortSignal;
}
/**
 * Async row iterator accepted by {@link CanvasInstance.registerTable}.
 * Materialized arrays are also accepted; iterables are forwarded row-by-row
 * to the provider's appender.
 */
export type RegisterRows = AsyncIterable<Record<string, unknown>> | Iterable<Record<string, unknown>>;
//# sourceMappingURL=types.d.ts.map