# Prior UJSX POC: Source Code Reference Source: `/workspace/aui/ujsx/` (Deno/JSR package `@ade/ujsx`) Summary: `/workspace/aui/SUMMARY.md` ## What to Preserve ### Transform Registry (`transform/registry.ts`) Priority-based transformation with continuation-passing style: ```typescript interface TransformRule { name: string; match: (node: T) => boolean; transform: (node: T, ctx: TransformContext, next: TransformFn) => U; priority?: number; } ``` Key pattern: `next` continuation allows recursive child transforms. Rules sorted by priority (higher = first). V2 extends this with `direction` and `schema` fields. ### HostConfig + Reconciler (`host/config.ts`) React-reconciler-inspired host adapter: ```typescript interface HostConfig { name: string; createRootContext(container, options?): RootCtx; createInstance(tag, props, ctx, parent?): Instance; createTextInstance(text, ctx, parent?): Instance; appendChild(parent, child, ctx): void; insertBefore?(parent, child, before, ctx): void; removeChild?(parent, child, ctx): void; prepareUpdate?(instance, tag, prevProps, nextProps, ctx): unknown | null; commitUpdate?(instance, payload, tag, prevProps, nextProps, ctx): void; } ``` The `createRoot()` reconciler is mount-only (MVP). V2 needs full reconciliation with key-based diffing. ### Graphology Host (`host/graphology.ts`) Dirty bitmask pattern on graph nodes: ```typescript const DIRTY = { Props: 1<<0, Content: 1<<1, Structure: 1<<2 } as const; ``` Edges use `parent->child#order` keys. Version tracking on nodes. Issue: `createInstance` has commented-out append logic, `prepareUpdate` uses `JSON.stringify` diffing. ### Streaming Transformer (`streaming/transformer.ts`) Chunk-based async iterable processor. V2 preserves this but flush should pass real ancestor context instead of empty arrays. ## What to Remove/Rewrite ### `UniversalProps` (`core/types.ts`) HTML-specific props that don't belong in a universal IR: - `onClick`, `onSubmit`, `onInput`, `onChange` (event handlers) - `className`, `class` (HTML-specific) - `data-*`, `aria-*` template keys - `__html` (dangerouslySetInnerHTML) V2 replaces with plain `Record`. ### `genId()` (`core/jsx.ts`) ```typescript function genId(): string { return `e_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; } ``` Non-deterministic. V2 uses counter-based or injectable IDs. ### Metadata Injection (`core/jsx.ts`) Every element gets `{ timestamp: new Date(), id: genId() }`. This is overhead without clear use in a universal IR. Move to host-specific concerns if needed. ## TypeBox Research Examples Source: `/workspace/research/typebox_research/ujsx/` ### `unist.ts` - Unist schema as TypeBox Module ```typescript export const Unist = Type.Module({ Data: Type.Object({},{additionalProperties: Type.Unknown()}), Point: Type.Object({ line: Type.Number(), column: Type.Number(), ... }), Position: Type.Object({ start: Type.Ref('Point'), end: Type.Ref("Point") }), Node: Type.Object({ type: Type.String(), data: Type.Optional(...), position: Type.Optional(...) }), Literal: Type.Composite([Type.Ref("Node"), Type.Object({ value: Type.Unknown() })]), Parent: Type.Composite([Type.Ref("Node"), Type.Object({ children: Type.Array(Type.Ref("Node")) })]), }) ``` ### `ujsx.ts` - UJSX schema as TypeBox Module ```typescript export const UJSX = Type.Module({ ElementMetadata: Type.Object({ id: Type.Optional(Type.String()), timestamp: Type.Optional(Type.Date()) }, { additionalProperties: Type.Unknown() }), Children: Type.Union([Type.Ref("UniversalNode"), Type.Array(Type.Ref("UniversalNode"))]), PropValue: Type.Union([Type.String(), Type.Number(), ..., Type.Function([...Type.Rest(Type.Array(Type.Unknown()))], Type.Void())]), UniversalProps: Type.Object({ id: Type.Optional(Type.String()), children: Type.Optional(Type.Ref("Children")) }, { additionalProperties: Type.Union([Type.Ref("PropValue"), Type.Undefined()]) }), RootElement: Type.Object({ type: Type.Literal("root"), props: Type.Intersect([...]), children: Type.Array(Type.Ref("UniversalNode")), ... }), UniversalElement: Type.Object({ type: Type.Union([Type.String(), Type.Function([Type.Ref("UniversalProps")], Type.Ref("UniversalNode"))]), props: Type.Ref("UniversalProps"), children: Type.Array(Type.Ref("UniversalNode")), ... }), }) ``` Key insight: `Type.Module` creates a `TModule` whose `$defs` is a live `string → TSchema` map. Access via `ValuePointer.Get(UJSX, "$defs/Children")`. Add at runtime via `ValuePointer.Set()`. Import resolved schemas via `UJSX.Import("Element")`. Note: `ElementMetadata` is defined twice in the research file (duplicate). V2 should clean this up and likely drop metadata from the core schema entirely. ### ts2typebox CLI tool `ts2typebox` can convert TypeScript types to TypeBox defs but has issues with complex types (JSDoc comments, linked references). Useful for basic types, unreliable for complex ones like unist/mdast type definitions.