/** * The neutral `MediaPlan` intermediate representation and its canonical serializers. * * @remarks * Internal sibling of the `@nhtio/adk/batteries/media` entry. All three front-ends — the * chainable builder, the pipe-string parser, and the JSON ops array — compile to this one IR, * and the step runtime consumes only this IR. Invariants (frozen design, section 0.7): * * - **Serializable.** No live `RegExp`, `Media`, or function values — regexes are * `{ source, flags }`, media refs are typed handles. A plan can be logged, content-hashed, * and embedded in a tool result. * - **Round-trip is fixed-point.** `parsePipe(toPipe(plan))` produces an equal plan and * `toPipe` is idempotent. `toPipe(parsePipe(s)) === s` is NOT promised (e.g. `2,3,4,5` * renders as `2-5`). * - **Engine-agnostic.** Steps name verbs, never engines. */ /** * A serializable regex reference. Never a live `RegExp` in the IR. */ export interface RegExpRef { /** The regex source, exactly as `RegExp.prototype.source` would report it. */ source: string; /** Sorted flag characters (canonicalized — `gi`, never `ig`). */ flags: string; } /** * A reference to another media participating in a multi-input verb (`merge`, `diff`, * `apply_patch`, `slides.update_image`). * * @remarks * The `id` variant is the canonical model-facing form — the pipe syntax is an inline * `@id` token (`merge with=@018f…`) and the ops form carries the same id. The `builder` * variant is implementor-only (a nested chain: `mp(a).diff(mp(b).convert('txt'))`) and is * not expressible in a flat pipe string. */ export type MediaRef = { kind: 'id'; id: string; } | { kind: 'builder'; plan: MediaPlan; }; /** Scalar arg values the flat pipe grammar can express directly. */ export type MediaArgScalar = string | number | boolean | RegExpRef | MediaRef; /** * A structured (JSON-shaped) arg value. In the pipe surface these are written as quoted JSON * (`updates='[{"address":"B2","value":3}]'`); in ops they are plain JSON. `null` is legal only * inside structured values (cell values), never as a top-level scalar. */ export type MediaArgJson = string | number | boolean | null | MediaArgJson[] | { [key: string]: MediaArgJson; }; /** * The value space of a single verb arg in the IR. * * @remarks * Flat lists (`types=image,font` → `['image','font']`) are `MediaArgScalar[]`. Whether a * value parsed from quoted JSON or a flat token is decided by the verb's arg schema — the IR * stores the final shape only. */ export type MediaArgValue = MediaArgScalar | MediaArgScalar[] | MediaArgJson; /** Source span carried by steps parsed from a pipe string, for error mapping. */ export interface SourceSpan { /** Zero-based character offset into the source string. */ offset: number; /** One-based line number. */ line: number; /** One-based column number. */ col: number; /** Length of the spanned text in characters. */ length: number; } /** One transform step: a canonical verb id plus its validated content args. */ export interface MediaStep { /** * Canonical verb id — dot-namespaced snake_case (`convert`, `select`, `extract.text`, * `sheet.update_cells`, `image.resize`). */ verb: string; /** Validated content args for this verb. */ args: Record; /** Present when the step came from a pipe string; absent for builder/ops origins. */ span?: SourceSpan; } /** The neutral plan: an ordered, linear list of steps. No branching. */ export interface MediaPlan { /** The ordered transform steps. */ steps: MediaStep[]; } /** The JSON ops front-end's step shape — identical to {@link MediaStep} minus the span. */ export interface MediaOp { /** The canonical (or foldable) verb id. */ verb: string; /** The verb's named args. */ args: Record; } /** `true` when `value` is a {@link RegExpRef}. */ export declare const isRegExpRef: (value: unknown) => value is RegExpRef; /** `true` when `value` is a {@link MediaRef}. */ export declare const isMediaRef: (value: unknown) => value is MediaRef; /** Canonicalize regex flags: validate against JS flags and sort. */ export declare const canonicalFlags: (flags: string) => string; /** * Render a {@link MediaPlan} to its canonical pipe string. * * @remarks * Total for every plan except those containing builder-variant media refs, which throw * {@link E_MEDIA_NOT_PIPE_EXPRESSIBLE}. Structured args render as quoted JSON. The output is * canonical: dot-namespaced verbs render as space-separated words, number runs compress to * ranges, strings quote per the frozen predicate. * * @param plan - The plan to render. * @returns The canonical pipe expression. */ export declare const toPipe: (plan: MediaPlan) => string; /** * Render a {@link MediaPlan} to its JSON ops array. Total — every plan has an ops form. * * @param plan - The plan to render. * @returns The ops array (spans stripped). */ export declare const toOps: (plan: MediaPlan) => MediaOp[]; /** * Build a {@link MediaPlan} from a JSON ops array. The inverse of {@link toOps}. * * @remarks * Performs structural normalization only (verb-id folding via the caller's verb table happens * in validation, not here). Steps carry no spans. * * @param ops - The ops array. * @returns The equivalent plan. */ export declare const fromOps: (ops: MediaOp[]) => MediaPlan;