@stacksjs/stx
Version:
A performant UI Framework. Powered by Bun.
286 lines • 9.16 kB
TypeScript
import type { Position } from './source-maps';
// =============================================================================
// Node Guards
// =============================================================================
export declare function isDocumentNode(node: ASTNode): node is DocumentNode;
export declare function isTextNode(node: ASTNode): node is TextNode;
export declare function isExpressionNode(node: ASTNode): node is ExpressionNode;
export declare function isDirectiveNode(node: ASTNode): node is DirectiveNode;
export declare function isComponentNode(node: ASTNode): node is ComponentNode;
export declare function isElementNode(node: ASTNode): node is ElementNode;
export declare function isAttributeNode(node: ASTNode): node is AttributeNode;
export declare function isCommentNode(node: ASTNode): node is CommentNode;
export declare function isScriptNode(node: ASTNode): node is ScriptNode;
export declare function isStyleNode(node: ASTNode): node is StyleNode;
/**
* Create a document node
*/
export declare function createDocument(children?: ASTNode[], loc?: SourceLocation): DocumentNode;
/**
* Create a text node
*/
export declare function createText(value: string, loc?: SourceLocation): TextNode;
/**
* Create an expression node
*/
export declare function createExpression(expression: string, escaped?: boolean, loc?: SourceLocation): ExpressionNode;
/**
* Create a directive node
*/
export declare function createDirective(name: string, params?: string | null, body?: ASTNode[] | null, loc?: SourceLocation): DirectiveNode;
/**
* Create a component node
*/
export declare function createComponent(name: string, attributes?: AttributeNode[], children?: ASTNode[], selfClosing?: boolean, loc?: SourceLocation): ComponentNode;
/**
* Create an element node
*/
export declare function createElement(tag: string, attributes?: AttributeNode[], children?: ASTNode[], loc?: SourceLocation): ElementNode;
/**
* Create an attribute node
*/
export declare function createAttribute(name: string, value?: string | ExpressionNode | null, loc?: SourceLocation): AttributeNode;
/**
* Create a comment node
*/
export declare function createComment(value: string, style?: 'html' | 'stx', loc?: SourceLocation): CommentNode;
/**
* Create a script node
*/
export declare function createScript(content: string, attributes?: AttributeNode[], loc?: SourceLocation): ScriptNode;
/**
* Create a style node
*/
export declare function createStyle(content: string, attributes?: AttributeNode[], scoped?: boolean, loc?: SourceLocation): StyleNode;
/**
* Walk the AST and call visitor callbacks
*/
export declare function walkAST(node: ASTNode, visitor: ASTVisitor, parent?: ASTNode | null): void;
/**
* Get child nodes of a node
*/
export declare function getChildren(node: ASTNode): ASTNode[];
/**
* Clone an AST node deeply
*/
export declare function cloneNode<T extends ASTNode>(node: T): T;
/**
* Replace a node in the AST
*/
export declare function replaceNode(root: DocumentNode, target: ASTNode, replacement: ASTNode | ASTNode[]): void;
/**
* Remove a node from the AST
*/
export declare function removeNode(root: DocumentNode, target: ASTNode): void;
/**
* Find all nodes matching a predicate
*/
export declare function findNodes(root: ASTNode, predicate: (node: ASTNode) => boolean): ASTNode[];
/**
* Find all nodes of a specific type
*/
export declare function findNodesByType<T extends ASTNode['type']>(root: ASTNode, type: T): Extract<ASTNode, { type: T }>[];
/**
* Find all directives by name
*/
export declare function findDirectives(root: ASTNode, name: string): DirectiveNode[];
/**
* Find all components by name
*/
export declare function findComponents(root: ASTNode, name: string): ComponentNode[];
/**
* Find all elements by tag name
*/
export declare function findElements(root: ASTNode, tag: string): ElementNode[];
/**
* Get all expression nodes in the AST
*/
export declare function getExpressions(root: ASTNode): ExpressionNode[];
/**
* Get all directive names used in the template
*/
export declare function getDirectiveNames(root: ASTNode): Set<string>;
/**
* Get all component names used in the template
*/
export declare function getComponentNames(root: ASTNode): Set<string>;
/**
* Generate code from AST
*/
export declare function generateCode(node: ASTNode): string;
/**
* Source location in template
*/
export declare interface SourceLocation {
start: Position
end: Position
source?: string
}
/**
* Base interface for all AST nodes
*/
export declare interface BaseNode {
type: string
loc?: SourceLocation
parent?: ASTNode
}
/**
* Document root node
*/
export declare interface DocumentNode extends BaseNode {
type: 'Document'
children: ASTNode[]
}
/**
* Plain text content
*/
export declare interface TextNode extends BaseNode {
type: 'Text'
value: string
}
/**
* Expression interpolation: {{ expr }} or {!! expr !!}
*/
export declare interface ExpressionNode extends BaseNode {
type: 'Expression'
expression: string
escaped: boolean
raw: string
}
/**
* Directive: @name(params) ... @endname
*/
export declare interface DirectiveNode extends BaseNode {
type: 'Directive'
name: string
params: string | null
body: ASTNode[] | null
selfClosing: boolean
raw: string
}
/**
* Component: <ComponentName attr="value">...</ComponentName>
*/
export declare interface ComponentNode extends BaseNode {
type: 'Component'
name: string
attributes: AttributeNode[]
children: ASTNode[]
selfClosing: boolean
}
/**
* HTML Element: <tag attr="value">...</tag>
*/
export declare interface ElementNode extends BaseNode {
type: 'Element'
tag: string
attributes: AttributeNode[]
children: ASTNode[]
selfClosing: boolean
void: boolean
}
/**
* Attribute on element or component
*/
export declare interface AttributeNode extends BaseNode {
type: 'Attribute'
name: string
value: string | ExpressionNode | null
dynamic: boolean
}
/**
* Comment: <!-- comment --> or {{-- comment --}}
*/
export declare interface CommentNode extends BaseNode {
type: 'Comment'
value: string
style: 'html' | 'stx'
}
/**
* Script block: <script>...</script>
*/
export declare interface ScriptNode extends BaseNode {
type: 'Script'
content: string
attributes: AttributeNode[]
}
/**
* Style block: <style>...</style>
*/
export declare interface StyleNode extends BaseNode {
type: 'Style'
content: string
attributes: AttributeNode[]
scoped: boolean
}
/**
* Visitor callbacks for AST traversal
*/
export declare interface ASTVisitor {
enter?: (node: ASTNode, parent: ASTNode | null) => void | false
leave?: (node: ASTNode, parent: ASTNode | null) => void
Document?: { enter?: (node: DocumentNode) => void | false, leave?: (node: DocumentNode) => void }
Text?: { enter?: (node: TextNode) => void | false, leave?: (node: TextNode) => void }
Expression?: { enter?: (node: ExpressionNode) => void | false, leave?: (node: ExpressionNode) => void }
Directive?: { enter?: (node: DirectiveNode) => void | false, leave?: (node: DirectiveNode) => void }
Component?: { enter?: (node: ComponentNode) => void | false, leave?: (node: ComponentNode) => void }
Element?: { enter?: (node: ElementNode) => void | false, leave?: (node: ElementNode) => void }
Attribute?: { enter?: (node: AttributeNode) => void | false, leave?: (node: AttributeNode) => void }
Comment?: { enter?: (node: CommentNode) => void | false, leave?: (node: CommentNode) => void }
Script?: { enter?: (node: ScriptNode) => void | false, leave?: (node: ScriptNode) => void }
Style?: { enter?: (node: StyleNode) => void | false, leave?: (node: StyleNode) => void }
}
/**
* Union of all AST node types
*/
export type ASTNode = | DocumentNode
| TextNode
| ExpressionNode
| DirectiveNode
| ComponentNode
| ElementNode
| AttributeNode
| CommentNode
| ScriptNode
| StyleNode
/**
* Token types for lexer (reserved for future tokenizer implementation)
*/
declare type _TokenType = | 'TEXT'
| 'EXPRESSION_ESCAPED'
| 'EXPRESSION_UNESCAPED'
| 'DIRECTIVE_START'
| 'DIRECTIVE_END'
| 'COMMENT_HTML'
| 'COMMENT_STX'
| 'TAG_OPEN'
| 'TAG_CLOSE'
| 'TAG_SELF_CLOSE'
| 'EOF'
/**
* Simple template parser
*/
export declare class TemplateParser {
private source: string;
private pos: number;
private line: number;
private column: number;
private filePath?: string;
parse(template: string, filePath?: string): DocumentNode;
private parseChildren(stopAt?: RegExp): ASTNode[];
private parseNext(): ASTNode | null;
private parseText(): TextNode | null;
private parseExpression(escaped: boolean): ExpressionNode;
private parseDirective(): DirectiveNode;
private parseParenthesized(): string;
private parseStxComment(): CommentNode;
private parseHtmlComment(): CommentNode;
private parseTag(): ElementNode | ComponentNode;
private parseAttributes(): AttributeNode[];
private parseAttribute(): AttributeNode | null;
private parseScript(): ScriptNode;
private parseStyle(): StyleNode;
private advance(count?: number): void;
private skipWhitespace(): void;
private getPosition(): Position;
}