API / @aihu/compiler

@aihu/compiler

Compiler & tooling

Single File Component (.aihu) compiler — Rust binary + JS glue.

version
1.3.0
exports
51
values
39
types
12
01

_buildDeferredHydration

function
function _buildDeferredHydration(compiledCode: string, elementTag: string): string

Rewrite an interactive-island module so its `connectedCallback` waits for the element to scroll into view before mounting.

02

_buildStaticIsland

function
function _buildStaticIsland(compiledCode: string, elementTag: string): string

Build a static-island shim for a compiled module.

03

_clearTransformMemo

function
function _clearTransformMemo(): void

Test/diagnostic hook — wipe the memo and its counters.

04

_compileViaBackend

function
function _compileViaBackend( source: string, legacyArgs: string[], options: CompileEnvelopeOptions, ): EnvelopeReply

Run one compile through the active backend.

05

_deriveChildTags

function
function _deriveChildTags(compiledCode: string): string[]

Derive the `__aihu_child_tags__` set from SERVER-TARGET compiled code: the tags the compiled string renderer will actually look up, read off the `__aihu_schild('<tag>'` call sites the Rust codegen emitted.

06

_errMessage

function
function _errMessage(err: unknown): string

Best-effort message text for an unknown thrown value.

07

_foldCssEngineStyles

function
function _foldCssEngineStyles(compiledCode: string, css: string): string
08

_foldCssEngineStylesGlobal

function
function _foldCssEngineStylesGlobal( compiledCode: string, css: string, id: string, ): { code: string; virtualId: string } | null

Bug 6 — `shadowMode === 'light'` branch.

09

_foldSsrCssExport

function
function _foldSsrCssExport(compiledCode: string, css: string): string

Fold css-engine utility CSS into the SERVER target's `__aihu_css__` export.

10

_formatExtractCensus

function
function _formatExtractCensus( census: ReadonlyMap<string, { read: string; call: string }>, ): string[]

GX Phase 1 (#437-GX) — format the per-value extract census (the DA-e census pattern from #437: every build PRINTS the posture distribution, so the default-vs-declared migration story stays visible rather than silent).

11

_getCompilerNativeStateKind

function
function _getCompilerNativeStateKind(): CompilerNativeState['kind']

Returns the cached state kind (resolving if needed).

12

_globalizeAuthoredStyle

function
function _globalizeAuthoredStyle(code: string): string

Light-DOM (`shadowMode:'light'`) recipes: redirect the authored `@style` block's per-instance `host.adoptedStyleSheets = [__style__]` assignment to `document.adoptedStyleSheets` so the recipe's class-scoped CSS reaches the global cascade (a light-DOM host has no shadow root, making the original setter a silent no-op).

13

_hashIdForUtilityCss

function
function _hashIdForUtilityCss(id: string): string

Stable short hash for keying the virtual-CSS module per source-SFC id.

14

_injectAutoWiring

function
function _injectAutoWiring(code: string): string

Inject `_setMount(mount)` + `_setSignal(signal)` auto-wiring into a compiled `.aihu` module.

15

_injectLightScopeId

function
function _injectLightScopeId(code: string, lightScopeId: string): string

Fill the Rust codegen's `__AIHU_LIGHT_SCOPE_ID__` placeholder with the component's real light-DOM scope id (LDF §10 step 3).

16

_injectShadowMode

function
function _injectShadowMode( code: string, mode: 'light' | 'shadow', lightScopeId?: string, ): string

Inject `shadowMode: '...'` (and, for light mode, `lightScopeId: '...'` in the SAME options object) into the third argument of the emitted `defineElement('tag', defineComponent(...))` call — appending the options object when the call has two arguments, or merging the fields into an existing third argument (`$form` emits `, { formAssociated: true }`).

17

_isLayoutFile

function
function _isLayoutFile(rawId: string, layoutsDir: string): boolean

Is `rawId` a layout SFC (a `.aihu` file under the configured layouts dir)?

18

_isViteMissing

function
function _isViteMissing(err: unknown): boolean

Is this `import('vite')` rejection the ONE legitimate "there is no Vite here" case — a standalone `transform()` caller, a unit test, any non-Vite host?

19

_layoutTag

function
function _layoutTag(stem: string): string

Layout custom-element tag for a filename stem.

20

_lightScopeId

function
function _lightScopeId(id: string): string

Deterministic 8-hex-char scope id for a light-DOM component's `data-a` attribute (light-DOM leaf flip, LDF §10 step 1 / step 3).

21

_parseComponentTagsMarker

function
function _parseComponentTagsMarker(compiledCode: string): string[]

§22 — parse the `//

22

_parseExtractMarker

function
function _parseExtractMarker(code: string): { read: string; call: string } | null

GX Phase 1 (#437-GX) — parse the `//

23

_parseIslandMarker

function
function _parseIslandMarker(compiledCode: string): 'static' | 'interactive'

Read the compiler's AUTHORITATIVE island classification from the `//

24

_passivizeOutlet

function
function _passivizeOutlet(code: string): string

Collapse the reactive `<outlet>` boundary the Rust codegen emits into a passive `data-aihu-outlet` marker.

25

_resetCompileBackend

function
function _resetCompileBackend(): void

Reset the cached backend (tests).

26

_resetCompilerNative

function
function _resetCompilerNative(): void

Reset the cached state.

27

_resolveCompileBackend

function
function _resolveCompileBackend(): CompileBackend

Resolve (once) which backend serves compiles for this process.

28

_stripFailure

function
function _stripFailure( fn: 'transformWithOxc' | 'transformWithEsbuild', id: string, viteVersion: string, isServerEnv: boolean, err: unknown, ): string

The message for a strip that failed with Vite present — names the branch, the Vite version, the environment and the file, and says why it is fatal rather than swallowed.

29

_stripTypes

functionagent
async function _stripTypes( vite: ViteStripApi, code: string, id: string, isServerEnv: boolean, ): Promise<StripTypesResult>

Strip TypeScript from compiler output using whichever transform the resolved Vite exposes.

30

_transformMemoStats

function
function _transformMemoStats(): { size: number hits: number misses: number seeds: number }

Test/diagnostic hook — current memo size + hit/miss/seed counters.

31

aihuCompilerPlugin

function
function aihuCompilerPlugin(options?: AihuCompilerPluginOptions): VitePlugin
32

compileRouteMeta

function
function compileRouteMeta(source: string, id?: string): RouteMeta | null
33

compileSidecar

functionagent
function compileSidecar( source: string, id?: string, options?: { /** * #486 step 4 — emit the attribute/component-prop type layer * (`--strict-templates`). Default off: the surface stays byte-identical * to the pre-#486 sidecar. */ strictTemplates?: boolean /** * Build target threaded to the compiler binary (`--target`), same flag * `transform()` passes. Defaults to the binary's own default * (`universal`) when omitted. * * This is NOT cosmetic: `--target` changes what `compile_full_with_options` * produces (packages/compiler/src/bin/main.rs), which `sidecar_ts` is * derived from — e.g. a `target: 'client'` build elides server-only * artifacts. A caller that never passes this always type-checks against * the `universal` surface regardless of the project's actual configured * target, which can pass tsc on code the real build would elide or * reject. `islands`/`shadowMode` are deliberately NOT parameters here: * both are applied as JS-side post-processing on the RUNTIME JS output * (see `transform()`), never touch `sidecar_ts`, and have no bearing on * type-check accuracy. */ target?: 'client' | 'server' | 'universal' }, ): string

Compile an SFC to its TYPE-CHECK SURFACE and return it as a string — the `.aihu.ts` sidecar's content, without writing a file.

34

compileToAst

function
function compileToAst(source: string, id?: string): SfcAst
35

kebabComponentTag

function
function kebabComponentTag(raw: string): string

O1a (tag naming) — JS mirror of the Rust compiler's `tags::kebab_component_tag` (packages/compiler/src/tags.rs).

36

loadCompilerNative

function
function loadCompilerNative(): CompilerNativeState

Resolve (and cache) the native compiler addon.

37

transform

function
function transform( source: string, id: string, options?: { sidecarOut?: string target?: 'client' | 'server' | 'universal' /** Override the registered custom-element tag (default: file stem). Used for layouts. */ tag?: string /** * #486 step 4 — emit the sidecar's attribute/component-prop type layer * (`--strict-templates`). Affects only the type-check surface written to * `sidecarOut`; the compiled JS is identical either way. Default off. */ strictTemplates?: boolean }, ): { code: string; map: null }

Compile a .aihu source string to TypeScript.

38

_MEMO_MAX_ENTRIES

const
const _MEMO_MAX_ENTRIES

FIFO size bound.

39

VIRTUAL_UTILITY_PREFIX

const
const VIRTUAL_UTILITY_PREFIX

Virtual-module prefix used by the `shadowMode === 'light'` branch to route per-SFC utility CSS through Vite's built-in CSS pipeline.

40

AihuCompilerPluginOptions

interface
interface AihuCompilerPluginOptions {
  /**
   * When `true` (default), components the compiler classified as `'static'`
   * (read from the `// @aihu:island` marker via `_parseIslandMarker()`) are
   * emitted with a minimal HTML-only registration shim that ships **zero**
   * `@aihu/runtime` and `@aihu/signals` JS to the browser. Components
   * classified as `'interactive'` retain the full runtime path.
   *
   * Setting `islands: false` opts every component back into the unified
   * runtime path (Plan 3.2 baseline behaviour).
   */
  islands?: boolean

  /**
   * Project-wide rendering mode applied to every `.aihu` SFC compiled
   * by this plugin instance. When set, the plugin post-processes the
   * compiled JS to inject `, { shadowMode: '<mode>' }` as the third arg
   * to the emitted `defineElement(tag, defineComponent(...))` call.
   *
   * BINARY vocabulary (DA4 #437):
   * - `'shadow'` — shadow DOM (`attachShadow({ mode: 'open' })` internally;
   *               open is the only browser mode aihu's composition/hydration
   *               can use). `this.shadowRoot` is the non-null root.
   * - `'light'`  — **no shadow root.** The component mounts into its own
   *               element (`this.shadowRoot === null`). Required for global
   *               utility-class CSS frameworks like Tailwind, UnoCSS, Pico
   *               that rely on the cascade.
   *
   * Per-file override: the `$shadow: 'light' | 'shadow'` macro outranks this
   * config. Unset, pages/layouts default to `'light'` and leaves to
   * `'shadow'`.
   */
  shadowMode?: 'light' | 'shadow'

  /**
   * Build target threaded to the compiler binary (`--target`). Defaults to the
   * compiler's `universal` target (current behaviour). Set to `'client'` for a
   * browser bundle that must NOT ship the server `__agentBinding` (policy) and
   * instead gets the policy-free `@agent` opaque-ID dispatcher + the per-instance
   * `_registerAgentDispatcher` wiring the capability bridge reads after mount.
   * See `examples/agent-driven-demo`.
   */
  target?: 'client' | 'server' | 'universal'

  /**
   * Directory (relative to the project root) holding layout SFCs. Default:
   * `'src/layouts'`. Files under this directory are compiled in **layout mode**:
   * their custom element is registered under the namespaced tag
   * `aihu-layout-<stem>` (a layout stem like `app` is not a valid custom-element
   * name on its own), and their `<outlet>` lowers to a **passive**
   * `data-aihu-outlet` marker rather than the reactive route-driven boundary —
   * because `@aihu/app`'s client renderer fills the marker imperatively and the
   * reactive boundary would otherwise clear it on mount.
   *
   * Kept in sync with `@aihu/router`'s `layoutTagFor()` (`virtual:aihu-layouts`).
   */
  layoutsDir?: string
}

Options for `aihuCompilerPlugin()` (Plan 3.3 — Islands).

41

CompileEnvelope

interface
interface CompileEnvelope {
  envelope: number
  targets: Record<string, { js?: string; manifest?: string }>
  astJson?: string
  routeJson?: string
  diagnostics: unknown[]
}

The wire shape of a compile envelope (Rust `Envelope`, camelCase).

42

CompileEnvelopeOptions

interface
interface CompileEnvelopeOptions {
  tag?: string
  path?: string
  targets?: string[]
  emits?: Array<'js' | 'ast' | 'route' | 'manifest'>
  strictTemplates?: boolean
  exprParser?: string
}

Options forwarded to the Rust envelope API (Rust `EnvelopeOptions`).

43

RouteMeta

interface
interface RouteMeta {
  pattern?: string
  name?: string
  layout?: string
  middleware?: string[]
  ssr?: boolean
  params?: string[]
  head?: unknown
  /**
   * GX Phase 1 fan-out (#437-GX): the resolved `extract` policy — always
   * present in the binary's route-json output since 0.1.12 (the default is
   * recorded, never implied by absence). Typed loose here: consumers
   * normalize fail-closed (`deriveReadPolicy` in `@aihu/server`).
   */
  extract?: { read?: unknown; call?: unknown }
  /**
   * GX Phase 4 fan-out (#466): the `data:` governed-resource declaration
   * (70-governed-data-access §2.1) — present only when the route declares one
   * (0.1.14+). `type` keys the server registry's provider; `preview` lists
   * the locked-state fields (omitted when none declared). Consumers: the
   * server runtime's boot validation + generated loader, and the router Vite
   * layer's C486 sibling-loader conflict check (§4.7).
   */
  data?: { type?: string; preview?: string[] }
}

Structured `@route` metadata (the `.route.json` sidecar shape).

44

SfcAst

interface
interface SfcAst {
  /** Resolved custom-element tag name (meta.name → route.name → file stem). */
  tag: string
  /** AST schema version — bumped on any breaking shape change (semver-tied). */
  astVersion: 1
  /** The @style block, if the SFC declared one. */
  style: SfcStyleBlock | null
  /** Parsed template tree. null when the SFC has no @template block. */
  template: SfcNode[] | null
  /** SFC-level metadata. */
  meta: SfcMeta
  /**
   * The compiler-assigned light-DOM scope id for this component's `data-a`
   * attribute, present only when it resolved to `shadowMode: 'light'`
   * (light-DOM leaf flip, LDF §10 step 1). Absent (not just `undefined`, the
   * key itself omitted on the wire) for shadow-mode components — additive,
   * mirrors `aihu-css-core`'s `SfcAst.light_scope_id: Option<String>`.
   */
  lightScopeId?: string
}

Top-level AST export — one per .aihu SFC.

45

SfcMeta

interface
interface SfcMeta {
  /** From @meta { name } / @route { name } / file stem — never null after resolution. */
  name: string
}
46

SfcStyleBlock

interface
interface SfcStyleBlock {
  /** Verbatim CSS body of the @style block (braces stripped, $global token removed). */
  content: string
  /** 'scoped' (default) or 'global' (@style { $global ... }). */
  scope: 'scoped' | 'global'
}
47

StripTypesResult

interface
interface StripTypesResult {
  readonly code: string
  readonly map: null
  /** Rolldown-only hint; set ONLY on the last-resort no-transform branch. */
  readonly moduleType?: 'ts'
}

What the Vite plugin's `transform` hook hands back after the strip.

48

ViteStripApi

interface
interface ViteStripApi {
  readonly version?: string
  readonly transformWithOxc?: (
    code: string,
    id: string,
    // biome-ignore lint/suspicious/noExplicitAny: variance seam — see doc comment
    ...rest: any[]
  ) => Promise<{ code: string }>
  readonly transformWithEsbuild?: (
    code: string,
    id: string,
    // biome-ignore lint/suspicious/noExplicitAny: variance seam — see doc comment
    ...rest: any[]
  ) => Promise<{ code: string }>
}

The subset of the Vite module `_stripTypes` uses — the seam tests fake.

49

SfcAttr

type
type SfcAttr =
  | { kind: 'static'; name: string; value: string } // Form A
  | { kind: 'binding'; name: string; expr: string } // Form B
  | { kind: 'macro'; name: string; value: SfcMacroValue }

Discriminated union mirroring Rust `Attr` — the three class-forms key on `kind`.

50

SfcMacroValue

type
type SfcMacroValue =
  | { form: 'quoted'; value: string }
  | { form: 'curly'; expr: string }
  | { form: 'boolean' }
51

SfcNode

type
type SfcNode =
  | { kind: 'element'; tag: string; attrs: SfcAttr[]; children: SfcNode[] }
  | { kind: 'macroElement'; name: string; attrs: SfcAttr[]; children: SfcNode[] }
  | { kind: 'text'; value: string }
  | { kind: 'interpolation'; expr: string }
  | { kind: 'ifBlock'; branches: Array<{ cond: string; body: SfcNode[] }> }
  | {
      kind: 'eachBlock'
      list: string
      item: string
      idx: string | null
      key: string | null
      body: SfcNode[]
      emptyBody: SfcNode[] | null
    }
  | { kind: 'htmlBlock'; expr: string }

Discriminated union mirroring Rust `TemplateNode`.