Source code for srdatalog.viz.bundle

'''Build the JSON bundle the VS Code extension renders.

One function: `get_visualization_bundle(program)` returns a dict that
contains HIR, MIR, per-rule JIT, and a summary of the rules. Purely
in-memory — no disk I/O, no compile pipeline rerun on the C++ side.

The shape is stable across Nim and Python ports because both compilers
share the same HIR/MIR contract (the byte-match fixture tests guard
that invariant). The extension's language-agnostic renderer consumes
this bundle; only the source-manipulation front (parse/patch) is
language-specific.
'''

from __future__ import annotations

from typing import TYPE_CHECKING

from srdatalog.ir.hir.emit import hir_to_obj
from srdatalog.ir.mir.print import print_mir_sexpr
from srdatalog.ir.pipeline import compile_program

if TYPE_CHECKING:
  from srdatalog.dsl import Program


[docs] def get_visualization_bundle( program: Program, project_name: str = "VizProject", *, include_jit: bool = True, ) -> dict: '''Return an in-memory bundle of everything the extension renders. Shape: { "hir": {...}, # HIR JSON (hir_to_obj output) "mir": "(program ...)", # MIR S-expr "jit": {name: cpp}, # per-rule complete runner code (omitted if include_jit=False) "rules": [ {...}, ... ], # rule summary for sidebar "project_name": str, # echo of the arg (for titles) "has_jit": bool, # whether the JIT block was included } `include_jit=False` skips emitting the per-rule C++ kernel code. On doop (78 rules, 96 runners) that drops the bundle from ~3 MB to ~300 KB — important for Jupyter cell rerun latency. The HIR / MIR / rule summary are always included since they're cheap and drive the graph view. Pass `include_jit=True` (the CLI default) when the user explicitly wants to inspect generated kernels. ''' cr = compile_program(program, project_name) bundle = { "hir": hir_to_obj(cr.hir), "mir": print_mir_sexpr(cr.mir), "rules": [_rule_summary(rule) for rule in program.rules], "relations": [r.name for r in program.relations], "project_name": project_name, "has_jit": include_jit, } if include_jit: bundle["jit"] = dict(cr.per_rule_runners) return bundle
def _rule_summary(rule) -> dict: '''Per-rule sidebar entry — name, head rels, body size, plans.''' return { "name": rule.name, "heads": [h.rel for h in rule.heads], "body_size": len(rule.body), "plans": [ { "delta": p.delta, "var_order": list(p.var_order), "clause_order": list(p.clause_order), } for p in rule.plans ], "count": rule.count, "semi_join": rule.semi_join, }