| 245 | * @returns openui-lang source text (multiple statements joined by newlines) |
| 246 | */ |
| 247 | export function jsonToOpenUI( |
| 248 | json: ElementNode, |
| 249 | library: Library, |
| 250 | options?: SerializeOptions, |
| 251 | ): string { |
| 252 | const paramMap = compileSchema(library.toJSONSchema()); |
| 253 | const collector = new StatementCollector(); |
| 254 | |
| 255 | // Serialize root — this recursively registers all child statements |
| 256 | const rootExpr = serializeElementExpr(json, paramMap, collector); |
| 257 | const rootId = json.statementId || "root"; |
| 258 | |
| 259 | // Build output: root first, then children (depth-first post-order), then state |
| 260 | const lines: string[] = []; |
| 261 | |
| 262 | // Root statement |
| 263 | lines.push(`${rootId} = ${rootExpr}`); |
| 264 | |
| 265 | // Child statements (already in depth-first post-order from collector) |
| 266 | for (const stmt of collector.getStatements()) { |
| 267 | // Skip root if it was also registered in collector |
| 268 | if (stmt.id === rootId) continue; |
| 269 | lines.push(stmt.text); |
| 270 | } |
| 271 | |
| 272 | // State declarations |
| 273 | if (options?.stateDeclarations) { |
| 274 | const stateLines = serializeStateDeclarations(options.stateDeclarations, paramMap, collector); |
| 275 | lines.push(...stateLines); |
| 276 | } |
| 277 | |
| 278 | return lines.join("\n"); |
| 279 | } |