@obarlik/streaming-pipeline-core
Version:
🔄 Memory-efficient circular buffer streaming pipeline with universal processing - by Codechu
119 lines (118 loc) • 3.51 kB
JavaScript
/**
* Abstract Syntax Tree (AST) support for streaming pipeline
* Enables parse-only and render-from-AST operations
*/
// AST utilities
export class ASTUtils {
/**
* Convert ContentSegment array to AST
*/
static segmentsToAST(segments) {
return {
type: 'document',
content: '',
children: segments.map(segment => ({
type: segment.type,
content: segment.content,
data: segment.data,
children: segment.children?.map((child) => ({
type: child.type,
content: child.content,
data: child.data
}))
}))
};
}
/**
* Convert AST to ContentSegment array
*/
static astToSegments(ast) {
if (!ast.children) {
return [{
type: ast.type,
content: ast.content,
data: ast.data
}];
}
return ast.children.map(child => ({
type: child.type,
content: child.content,
data: child.data,
children: child.children?.map(grandchild => ({
type: grandchild.type,
content: grandchild.content,
data: grandchild.data
}))
}));
}
/**
* Walk AST with visitor pattern
*/
static walkAST(ast, visitor, parent) {
const results = [];
const result = visitor.visitNode(ast, parent);
if (result !== undefined) {
results.push(result);
}
if (ast.children && visitor.visitChildren) {
const childResults = visitor.visitChildren(ast);
results.push(...childResults);
}
else if (ast.children) {
for (const child of ast.children) {
results.push(...this.walkAST(child, visitor, ast));
}
}
return results;
}
/**
* Transform AST with transformer pattern
*/
static transformAST(ast, transformer) {
let transformedNode = transformer.canTransform(ast)
? transformer.transform(ast)
: ast;
if (transformedNode.children) {
transformedNode = {
...transformedNode,
children: transformedNode.children.map(child => this.transformAST(child, transformer))
};
}
return transformedNode;
}
/**
* Find nodes by type
*/
static findNodesByType(ast, type) {
const results = [];
if (ast.type === type) {
results.push(ast);
}
if (ast.children) {
for (const child of ast.children) {
results.push(...this.findNodesByType(child, type));
}
}
return results;
}
/**
* Calculate AST statistics
*/
static getASTStats(ast) {
let nodeCount = 0;
let maxDepth = 0;
const typeDistribution = {};
function traverse(node, depth) {
nodeCount++;
maxDepth = Math.max(maxDepth, depth);
typeDistribution[node.type] = (typeDistribution[node.type] || 0) + 1;
if (node.children) {
for (const child of node.children) {
traverse(child, depth + 1);
}
}
}
traverse(ast, 0);
return { nodeCount, maxDepth, typeDistribution };
}
}