import type { StxOptions } from './types';
/**
 * Scan a template for `<script>` tags in browser order: each opening tag is
 * closed by the **first** subsequent `</script>` (case-insensitive), and the
 * scanner then continues from after that close tag. This matches how HTML
 * parsers tokenize `<script>` as a RAWTEXT element — they don't re-scan the
 * body for more `<script` openings.
 *
 * A plain regex like `/<script[^>]*>([\s\S]*?)<\/script>/g` doesn't give you
 * this property: if a script body contains the literal text `<script client>`
 * (e.g. inside a JS comment), the regex matches it as a fresh script tag,
 * which breaks downstream TypeScript transpilation and directive parsing.
 *
 * `skipAttrs` lets callers drop tags whose attribute string contains certain
 * patterns (e.g. `server`, `src=`, `data-stx-scoped`).
 */
export declare function scanScriptTags(html: string, opts?: { skipAttrs?: RegExp }): Array<{ fullMatch: string, attrs: string, body: string, start: number, end: number }>;
/**
 * Parse a loop argument — accepts every syntax stx supports at runtime.
 *
 * ```
 * parseLoopExpression('items as item')                → { style:'as', iterable:'items',     itemVar:'item', indexVar:null }
 * parseLoopExpression('items as idx => item')         → { style:'as', iterable:'items',     itemVar:'item', indexVar:'idx' }
 * parseLoopExpression('items as item, idx')           → { style:'as', iterable:'items',     itemVar:'item', indexVar:'idx' }
 * parseLoopExpression('items as (item, idx)')         → { style:'as', iterable:'items',     itemVar:'item', indexVar:'idx' }
 * parseLoopExpression('obj.list as item')             → { style:'as', iterable:'obj.list',  itemVar:'item', indexVar:null }
 * parseLoopExpression('item in items')                → { style:'in', iterable:'items',     itemVar:'item', indexVar:null }
 * parseLoopExpression('(item, idx) in items')         → { style:'in', iterable:'items',     itemVar:'item', indexVar:'idx' }
 * parseLoopExpression('item of items')                → { style:'in', iterable:'items',     itemVar:'item', indexVar:null }
 * ```
 */
export declare function parseLoopExpression(expr: string): ParsedLoopExpression;
/**
 * Check if template uses STX signals syntax.
 *
 * STX directives work seamlessly on both server and client:
 * - `@if`, `@else` - Conditional rendering
 * - `@for` - List iteration
 * - `@show` - Toggle visibility (keeps element in DOM)
 * - `@model` - Two-way binding
 * - `@bind:attr` - Dynamic attribute binding
 * - `@class`, `@style` - Dynamic class/style binding
 * - `@click`, `@submit` - Event handling
 * - Scripts containing `state(`, `derived(`, `effect(` - Signal APIs
 *
 * Server-side directives are processed at build time.
 * Remaining directives with reactive values are handled by the client runtime.
 */
export declare function hasSignalsSyntax(template: string): boolean;
/**
 * Convert @if(expr)...@endif directive blocks to attribute-style for signal templates.
 *
 * This allows the signals runtime to handle reactive conditionals instead of
 * evaluating them at build time with mock values. `@if`/`v-if` (which compiles to
 * `@if`) thus behave as interchangeable sugar for `:if` on signal pages — including
 * `@if`/`@elseif`/`@else` chains, which become a reactive sibling chain driven by
 * the runtime's `findIfChain`/`bindIfChain` (it already understands `@else-if`/`@else`).
 *
 * Converts:
 *   @if(loading())
 *     <div>Loading...</div>
 *   @endif
 *
 * To:
 *   <template @if="loading()">
 *     <div>Loading...</div>
 *   </template>
 *
 * And a branching chain:
 *   @if(a()) <p>A</p> @elseif(b()) <p>B</p> @else <p>C</p> @endif
 *
 * To adjacent siblings the runtime walks via nextElementSibling:
 *   <p @if="a()">A</p>
 *   <p @else-if="b()">B</p>
 *   <p @else>C</p>
 *
 * Note: Uses <template> wrapper for branches with multiple children or text nodes.
 */
export declare function convertSignalDirectivesToAttributes(template: string, context?: Record<string, any>): string;
/**
 * SSR pre-eval for literal-valued reactive conditional attributes
 * (stacksjs/stx#1739, Phase A).
 *
 * The reactive `:if` / `:show` family (and the `x-if` / `x-show` /
 * attribute-form `@if` aliases) is normally bound at runtime via
 * `bindIf` / `bindShow`. When the attribute value is a pure literal
 * — feature-flag constants like `:if="false"`, dev-only debug blocks
 * like `:if="true"`, etc. — there's no reason to ship the element +
 * runtime binding. Pre-evaluate and:
 *
 *   - truthy literal ⇒ strip the attribute, keep the element
 *   - falsy literal  ⇒ drop the element entirely (children included)
 *
 * Phase A intentionally handles ONE element at a time — `:else-if` /
 * `:else` chain rebalancing is Phase B. So `:if="false"` with a sibling
 * `:else` still drops the if-element; the else still emits as it would
 * have, and the runtime picks correctly (chains where the first
 * branch is gone become "always show the else branch").
 *
 * Skips:
 *   - non-literal expressions (let the runtime own them)
 *   - the block-form `@if(...)@endif` directive — that has its own
 *     server-side handler (`processConditionals`)
 *   - elements inside `<script>` / `<style>` bodies
 */
export declare function preEvalLiteralReactiveIfs(template: string): string;
/**
 * Convert @for(item in items())...@endfor directive blocks to attribute-style.
 *
 * Converts:
 *   @for(item in items())
 *     <div>{{ item.name }}</div>
 *   @endfor
 *
 * To:
 *   <template @for="item in items()">
 *     <div>{{ item.name }}</div>
 *   </template>
 */
export declare function convertSignalLoopsToAttributes(template: string, context?: Record<string, any>): string;
export declare function processScriptSetup(template: string, filePath?: string): Promise<{ output: string, setupCode: string | null }>;
/**
 * Extract exported variable names from setup script.
 * Returns variables that should be exposed to the template.
 * Only extracts TOP-LEVEL declarations, not variables inside nested functions.
 */
export declare function extractExports(setupContent: string): string;
/**
 * Main orchestrator for signal processing.
 *
 * Detects signal syntax, wraps scripts in setup functions,
 * injects the signals runtime and browser runtime.
 */
export declare function processSignals(template: string, options: StxOptions, filePath?: string): Promise<string>;
/**
 * Parsed form of a loop expression (`@for` / `@foreach` argument).
 *
 * `style: 'as'` — "iterable as item" / "iterable as idx => item" / "iterable as (item, idx)"
 * `style: 'in'` — "item in iterable" / "(item, idx) in iterable" / "item of iterable"
 * `style: 'unknown'` — fell through all parsers; iterable is `null`
 */
export declare interface ParsedLoopExpression {
  style: 'as' | 'in' | 'unknown'
  iterable: string | null
  itemVar: string | null
  indexVar: string | null
}
