getsyntux 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/dist/client.mjs +2 -2
- package/dist/client.mjs.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<i>syntux</i> is the generative UI library for the web.
|
|
4
|
+
<i>syntux</i> is the generative UI library for the web.
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
You give it a <code>value</code> and it designs the UI to display it.
|
|
5
9
|
</p>
|
|
6
10
|
|
|
7
11
|
---
|
|
@@ -118,6 +122,8 @@ export default function Home(){
|
|
|
118
122
|
|
|
119
123
|
</sup>
|
|
120
124
|
|
|
125
|
+
Make sure components are marked with `"use client"`.
|
|
126
|
+
|
|
121
127
|
#### Custom actions
|
|
122
128
|
|
|
123
129
|
Perform server actions, attached automatically to component events:
|
|
@@ -134,10 +140,11 @@ export default function Home(){
|
|
|
134
140
|
}} />
|
|
135
141
|
}
|
|
136
142
|
```
|
|
143
|
+
<sup>
|
|
137
144
|
|
|
138
|
-
The name of the action should specify its purpose (it is seen by the LLM).
|
|
145
|
+
**Note**: The name of the action should specify its purpose (it is seen by the LLM). Use `defineTool` to add further context to actions. See the [documentation](https://github.com/puffinsoft/syntux/wiki).
|
|
139
146
|
|
|
140
|
-
|
|
147
|
+
</sup>
|
|
141
148
|
|
|
142
149
|
---
|
|
143
150
|
|
package/dist/client.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use client";import{readStreamableValue as
|
|
2
|
-
`);return e.length>1?(e.slice(0,e.length-1).forEach(
|
|
1
|
+
"use client";import{readStreamableValue as J}from"@ai-sdk/rsc";import{useEffect as O,useReducer as U,useRef as V}from"react";import{Fragment as _}from"react";import{Fragment as A,jsx as d}from"react/jsx-runtime";import{createElement as F}from"react";var R=(r,t)=>t==="$"?r:t.split(".").reduce((e,i)=>e==null?void 0:e[i],r),p=(r,t,e)=>e.startsWith("$item.")?(e=e.slice(6),R(t,e)):e==="$item"?t:R(r,e),$=new Set(["dangerouslySetInnerHTML"]),P=(r,t,e,i)=>{if(!e)return e;if("$action"in e){let n=i[e.$action];if(!n)return()=>{};let s=e.args.map(o=>o&&typeof o=="object"&&"$bind"in o?p(r,t,o.$bind):o);return o=>{n.fn(...s)}}if("$bind"in e){let n=p(r,t,e.$bind);return Object.keys(n).forEach(s=>{$.has(s)&&delete n[s]}),n}return Object.keys(e).forEach(n=>{if($.has(n)){delete e[n];return}let s=e[n];typeof s=="object"&&(e[n]=P(r,t,s,i))}),e},x=(r,t,e)=>typeof e=="object"?p(r,t,e.$bind):e;function h(r){var M,S;let{id:t,componentMap:e,childrenMap:i,global:n,local:s,allowedComponents:o,actions:c}=r,a=e[t];if(a.type==="TEXT")return d(A,{children:x(n,s,a.content)});let f=(M=a.props)==null?void 0:M.source;if(a.type==="__ForEach__"&&f){let l=p(n,s,f);if(!Array.isArray(l))return null;let m=i[a.id];return d(A,{children:m==null?void 0:m.map((T,N)=>d(_,{children:l.map((v,L)=>F(h,{...r,id:T,local:v,key:L}))},N))})}let u=o[a.type]||a.type,g=P(n,s,a.props,c),E=x(n,s,a.content),I=((S=i[a.id])==null?void 0:S.map((l,m)=>d(h,{...r,id:l},m)))||[],C=[E,...I].filter(l=>l!=null);return C.length>0?d(u,{...g,children:C}):d(u,{...g})}var y=class{buffer="";schema={childrenMap:{},componentMap:{},root:null};addDelta(t){this.buffer+=t;let e=this.buffer.split(`
|
|
2
|
+
`);return e.length>1?(e.slice(0,e.length-1).forEach(i=>this.handleLine(i)),this.buffer=e[e.length-1],!0):!1}handleLine(t){try{let e=JSON.parse(t),{childrenMap:i,componentMap:n}=this.schema;n[e.id]=e,e.parentId===null?this.schema.root=e:(i[e.parentId]||(i[e.parentId]=[]),i[e.parentId].push(e.id))}catch{}}finish(){this.handleLine(this.buffer),this.buffer=""}};import{Fragment as w,jsx as b}from"react/jsx-runtime";function ee({value:r,allowedComponents:t,inputStream:e,placeholder:i,actions:n}){var a;let[,s]=U(f=>f+1,0),o=V(null);O(()=>{o.current=new y,(async()=>{for await(let u of J(e))o.current&&u!==void 0&&o.current.addDelta(u)&&s()})().then(()=>{o.current.finish(),s()})},[e]);let c=(a=o==null?void 0:o.current)==null?void 0:a.schema;return b(w,{children:c!=null&&c.root?b(h,{id:c.root.id,componentMap:c.componentMap,childrenMap:c.childrenMap,allowedComponents:t,global:r,local:r,actions:n||{}}):b(w,{children:i})})}export{ee as GeneratedClient,h as Renderer};
|
|
3
3
|
//# sourceMappingURL=client.mjs.map
|
package/dist/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/GeneratedClient.tsx","../src/client/Renderer.tsx","../src/ResponseParser.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport { StreamableValue, readStreamableValue } from '@ai-sdk/rsc';\r\nimport React, { JSX, useEffect, useReducer, useRef, useState } from 'react';\r\nimport { Renderer } from './Renderer';\r\nimport { ResponseParser } from '../ResponseParser';\r\nimport { ContextfulAction } from 'src/types';\r\n\r\n/**\r\n * Client wrapper for Renderer that handles streaming and parsing with server.\r\n */\r\nexport function GeneratedClient({\r\n value,\r\n allowedComponents,\r\n inputStream,\r\n placeholder,\r\n actions\r\n}: {\r\n value: any,\r\n allowedComponents: Record<string, React.ComponentType<any> | string>,\r\n inputStream: StreamableValue<string>,\r\n placeholder?: JSX.Element,\r\n actions?: Record<string, ContextfulAction>\r\n}) {\r\n const [, forceUpdate] = useReducer(x => x + 1, 0);\r\n const parser = useRef<ResponseParser | null>(null);\r\n\r\n useEffect(() => {\r\n // forcibly create a new one for HMR\r\n parser.current = new ResponseParser();\r\n\r\n const parseStream = async () => {\r\n for await (const delta of readStreamableValue(inputStream)) {\r\n if (parser.current && delta !== undefined) {\r\n if (parser.current.addDelta(delta)) {\r\n forceUpdate();\r\n }\r\n }\r\n }\r\n };\r\n\r\n parseStream().then(() => {\r\n parser.current.finish();\r\n forceUpdate();\r\n });\r\n }, [inputStream]);\r\n\r\n const schema = parser?.current?.schema;\r\n\r\n return (\r\n <>\r\n {schema?.root ?\r\n <Renderer id={schema.root.id} componentMap={schema.componentMap} childrenMap={schema.childrenMap} allowedComponents={allowedComponents} global={value} local={value} actions={actions || {}} />\r\n : <>{placeholder}</>}\r\n </>\r\n )\r\n}\r\n","\"use client\";\r\n\r\nimport { ComponentType, Fragment } from 'react'\r\nimport { ChildrenMap, ComponentMap, ContextfulAction, SchemaNode } from '../types';\r\n\r\n/**\r\n * lightweight implementation of lodash.get\r\n */\r\nconst resolvePath = (obj: any, path: string) => {\r\n if (path === '$') return obj;\r\n return path.split('.').reduce((acc, curr) => acc?.[curr], obj)\r\n}\r\n\r\n/**\r\n * parses binding protocol and performs property lookup w/ scope resolution\r\n */\r\nconst get = (global: any, local: any, path: string) => {\r\n if (path.startsWith(\"$item.\")) {\r\n path = path.slice(6)\r\n return resolvePath(local, path);\r\n } else {\r\n if (path === \"$item\") return local;\r\n return resolvePath(global, path);\r\n }\r\n}\r\n\r\n/**\r\n * recursively parses props for bindings, replacing with true values\r\n */\r\nconst resolveProps = (global: any, local: any, props: any, actions: Record<string, ContextfulAction>) => {\r\n if (!props) return props;\r\n if (\"$action\" in props) {\r\n const action = actions[props.$action];\r\n if (!action) return () => { };\r\n\r\n const resolvedArgs = props.args.map((arg: any) => {\r\n if (arg && typeof arg === \"object\" && \"$bind\" in arg) {\r\n return get(global, local, arg.$bind);\r\n } else {\r\n return arg;\r\n }\r\n })\r\n\r\n return (e: any) => {\r\n action.fn(...resolvedArgs)\r\n }\r\n }\r\n\r\n if (\"$bind\" in props) return get(global, local, props.$bind); // $bind may be falsy value\r\n Object.keys(props).forEach((key) => {\r\n const val = props[key];\r\n if (typeof val === \"object\") {\r\n props[key] = resolveProps(global, local, val, actions);\r\n }\r\n })\r\n return props;\r\n}\r\n\r\n/**\r\n * output node.content, with check for $bind\r\n*/\r\nconst renderContent = (global: any, local: any, content: any) => {\r\n if (typeof content === \"object\") {\r\n return get(global, local, content.$bind);\r\n } else {\r\n return content;\r\n }\r\n}\r\n\r\nconst voidElements = new Set([\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n])\r\n\r\nexport interface RendererProps {\r\n id: string;\r\n componentMap: ComponentMap;\r\n childrenMap: ChildrenMap;\r\n allowedComponents: Record<string, ComponentType<any> | string>;\r\n global: any;\r\n local: any;\r\n actions: Record<string, ContextfulAction>;\r\n}\r\n\r\n/**\r\n * Renders a UISchema recursively, in accordance to the spec.\r\n */\r\nexport function Renderer(props: RendererProps) {\r\n const {\r\n id, componentMap, childrenMap, global, local, allowedComponents, actions\r\n } = props;\r\n const element = componentMap[id];\r\n\r\n if (element.type === \"TEXT\") return <>{renderContent(global, local, element.content)}</>\r\n\r\n const sourceArrPath = element.props?.source;\r\n if (element.type === '__ForEach__' && sourceArrPath) {\r\n const sourceArr = get(global, local, sourceArrPath)\r\n if (!Array.isArray(sourceArr)) return null;\r\n\r\n const childrenArr = childrenMap[element.id];\r\n return <>{childrenArr?.map((childId: string, index: number) => <Fragment key={index}>\r\n {sourceArr.map((item: any, index1: number) => <Renderer {...props} id={childId} local={item} key={index1} />)}\r\n </Fragment>)}</>\r\n }\r\n\r\n const Component = allowedComponents[element.type] || element.type;\r\n const componentProps = resolveProps(global, local, element.props, actions);\r\n if (typeof Component === \"string\" && voidElements.has(Component)) {\r\n return <Component {...componentProps} />\r\n }\r\n\r\n return <Component {...componentProps}>\r\n {renderContent(global, local, element.content)}\r\n {childrenMap[element.id] && childrenMap[element.id].map((childId: string, index: number) => {\r\n return <Renderer\r\n key={index}\r\n {...props}\r\n id={childId}\r\n />\r\n })}\r\n </Component>\r\n}\r\n","import { SchemaNode, UISchema } from \"./types\";\r\n\r\n/**\r\n * Utility class for parsing UISchema from stream.\r\n */\r\nexport class ResponseParser {\r\n buffer = \"\"; // unflushed existing deltas w/o newline\r\n \r\n // schema assembled thus far\r\n schema: UISchema = {\r\n childrenMap: {},\r\n componentMap: {},\r\n root: null\r\n }\r\n\r\n /**\r\n * Update schema with latest data chunk.\r\n * \r\n * Handles multiline input gracefully; can be used to load entire schemas from cache.\r\n * \r\n * @param delta delta from stream.\r\n * @returns true if update is warranted, false otherwise.\r\n */\r\n addDelta(delta: string) {\r\n this.buffer += delta;\r\n const split = this.buffer.split(\"\\n\")\r\n if (split.length > 1) {\r\n split.slice(0, split.length - 1).forEach((line) => this.handleLine(line));\r\n this.buffer = split[split.length - 1];\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Parses a single line (full JSON object) and updates schema.\r\n * Generally should not be used when streaming data.\r\n */\r\n handleLine(line: string) {\r\n try {\r\n const node: SchemaNode = JSON.parse(line);\r\n\r\n const { childrenMap, componentMap } = this.schema;\r\n\r\n componentMap[node.id] = node;\r\n if (node.parentId === null) {\r\n this.schema.root = node;\r\n } else {\r\n if (!childrenMap[node.parentId]) childrenMap[node.parentId] = []\r\n childrenMap[node.parentId].push(node.id)\r\n }\r\n } catch (err) { /* probably markdown or generation inconsistency */ }\r\n }\r\n\r\n /**\r\n * Clears the buffer and handles any remaining information within.\r\n */\r\n finish(){\r\n this.handleLine(this.buffer);\r\n this.buffer = \"\";\r\n }\r\n}"],"mappings":"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","names":["readStreamableValue","useEffect","useReducer","useRef","Fragment","jsx","jsxs","createElement","resolvePath","obj","path","acc","curr","get","global","local","resolveProps","props","actions","action","resolvedArgs","arg","e","key","val","renderContent","content","voidElements","Renderer","_a","id","componentMap","childrenMap","allowedComponents","element","sourceArrPath","sourceArr","childrenArr","childId","index","item","index1","Component","componentProps","ResponseParser","delta","split","line","node","childrenMap","componentMap","Fragment","jsx","GeneratedClient","value","allowedComponents","inputStream","placeholder","actions","_a","forceUpdate","useReducer","x","parser","useRef","useEffect","ResponseParser","delta","readStreamableValue","schema","Renderer"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/GeneratedClient.tsx","../src/client/Renderer.tsx","../src/ResponseParser.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport { StreamableValue, readStreamableValue } from '@ai-sdk/rsc';\r\nimport React, { JSX, useEffect, useReducer, useRef, useState } from 'react';\r\nimport { Renderer } from './Renderer';\r\nimport { ResponseParser } from '../ResponseParser';\r\nimport { ContextfulAction } from 'src/types';\r\n\r\n/**\r\n * Client wrapper for Renderer that handles streaming and parsing with server.\r\n */\r\nexport function GeneratedClient({\r\n value,\r\n allowedComponents,\r\n inputStream,\r\n placeholder,\r\n actions\r\n}: {\r\n value: any,\r\n allowedComponents: Record<string, React.ComponentType<any> | string>,\r\n inputStream: StreamableValue<string>,\r\n placeholder?: JSX.Element,\r\n actions?: Record<string, ContextfulAction>\r\n}) {\r\n const [, forceUpdate] = useReducer(x => x + 1, 0);\r\n const parser = useRef<ResponseParser | null>(null);\r\n\r\n useEffect(() => {\r\n // forcibly create a new one for HMR\r\n parser.current = new ResponseParser();\r\n\r\n const parseStream = async () => {\r\n for await (const delta of readStreamableValue(inputStream)) {\r\n if (parser.current && delta !== undefined) {\r\n if (parser.current.addDelta(delta)) {\r\n forceUpdate();\r\n }\r\n }\r\n }\r\n };\r\n\r\n parseStream().then(() => {\r\n parser.current.finish();\r\n forceUpdate();\r\n });\r\n }, [inputStream]);\r\n\r\n const schema = parser?.current?.schema;\r\n\r\n return (\r\n <>\r\n {schema?.root ?\r\n <Renderer id={schema.root.id} componentMap={schema.componentMap} childrenMap={schema.childrenMap} allowedComponents={allowedComponents} global={value} local={value} actions={actions || {}} />\r\n : <>{placeholder}</>}\r\n </>\r\n )\r\n}\r\n","\"use client\";\r\n\r\nimport { ComponentType, Fragment } from 'react'\r\nimport { ChildrenMap, ComponentMap, ContextfulAction, SchemaNode } from '../types';\r\n\r\n/**\r\n * lightweight implementation of lodash.get\r\n */\r\nconst resolvePath = (obj: any, path: string) => {\r\n if (path === '$') return obj;\r\n return path.split('.').reduce((acc, curr) => acc?.[curr], obj)\r\n}\r\n\r\n/**\r\n * parses binding protocol and performs property lookup w/ scope resolution\r\n */\r\nconst get = (global: any, local: any, path: string) => {\r\n if (path.startsWith(\"$item.\")) {\r\n path = path.slice(6)\r\n return resolvePath(local, path);\r\n } else {\r\n if (path === \"$item\") return local;\r\n return resolvePath(global, path);\r\n }\r\n}\r\n\r\n\r\nconst blacklistedProps = new Set([\"dangerouslySetInnerHTML\"])\r\n/**\r\n * recursively parses props for bindings, replacing with true values\r\n */\r\nconst resolveProps = (global: any, local: any, props: any, actions: Record<string, ContextfulAction>) => {\r\n if (!props) return props;\r\n if (\"$action\" in props) {\r\n const action = actions[props.$action];\r\n if (!action) return () => { };\r\n\r\n const resolvedArgs = props.args.map((arg: any) => {\r\n if (arg && typeof arg === \"object\" && \"$bind\" in arg) {\r\n return get(global, local, arg.$bind);\r\n } else {\r\n return arg;\r\n }\r\n })\r\n\r\n return (e: any) => {\r\n action.fn(...resolvedArgs)\r\n }\r\n }\r\n\r\n if (\"$bind\" in props) { // $bind may be falsy value\r\n const resolved = get(global, local, props.$bind);\r\n Object.keys(resolved).forEach((key) => {\r\n if(blacklistedProps.has(key)){\r\n delete resolved[key];\r\n }\r\n })\r\n return resolved;\r\n }\r\n\r\n Object.keys(props).forEach((key) => {\r\n if (blacklistedProps.has(key)) {\r\n delete props[key];\r\n return;\r\n }\r\n\r\n const val = props[key];\r\n if (typeof val === \"object\") {\r\n props[key] = resolveProps(global, local, val, actions);\r\n }\r\n })\r\n return props;\r\n}\r\n\r\n/**\r\n * output node.content, with check for $bind\r\n*/\r\nconst renderContent = (global: any, local: any, content: any) => {\r\n if (typeof content === \"object\") {\r\n return get(global, local, content.$bind);\r\n } else {\r\n return content;\r\n }\r\n}\r\n\r\nexport interface RendererProps {\r\n id: string;\r\n componentMap: ComponentMap;\r\n childrenMap: ChildrenMap;\r\n allowedComponents: Record<string, ComponentType<any> | string>;\r\n global: any;\r\n local: any;\r\n actions: Record<string, ContextfulAction>;\r\n}\r\n\r\n/**\r\n * Renders a UISchema recursively, in accordance to the spec.\r\n */\r\nexport function Renderer(props: RendererProps) {\r\n const {\r\n id, componentMap, childrenMap, global, local, allowedComponents, actions\r\n } = props;\r\n const element = componentMap[id];\r\n\r\n if (element.type === \"TEXT\") return <>{renderContent(global, local, element.content)}</>\r\n\r\n const sourceArrPath = element.props?.source;\r\n if (element.type === '__ForEach__' && sourceArrPath) {\r\n const sourceArr = get(global, local, sourceArrPath)\r\n if (!Array.isArray(sourceArr)) return null;\r\n\r\n const childrenArr = childrenMap[element.id];\r\n return <>{childrenArr?.map((childId: string, index: number) => <Fragment key={index}>\r\n {sourceArr.map((item: any, index1: number) => <Renderer {...props} id={childId} local={item} key={index1} />)}\r\n </Fragment>)}</>\r\n }\r\n\r\n const Component = allowedComponents[element.type] || element.type;\r\n const componentProps = resolveProps(global, local, element.props, actions);\r\n\r\n const contentNode = renderContent(global, local, element.content);\r\n const childNodes = childrenMap[element.id]?.map((childId: string, index: number) => {\r\n return <Renderer\r\n key={index}\r\n {...props}\r\n id={childId}\r\n />\r\n }) || []\r\n\r\n const nodesToRender = [contentNode, ...childNodes].filter(node => node !== null && node !== undefined) // 0 is falsy\r\n\r\n if (nodesToRender.length > 0) {\r\n return <Component {...componentProps}>\r\n {nodesToRender}\r\n </Component>\r\n }\r\n\r\n return <Component {...componentProps} />\r\n}\r\n","import { SchemaNode, UISchema } from \"./types\";\r\n\r\n/**\r\n * Utility class for parsing UISchema from stream.\r\n */\r\nexport class ResponseParser {\r\n buffer = \"\"; // unflushed existing deltas w/o newline\r\n \r\n // schema assembled thus far\r\n schema: UISchema = {\r\n childrenMap: {},\r\n componentMap: {},\r\n root: null\r\n }\r\n\r\n /**\r\n * Update schema with latest data chunk.\r\n * \r\n * Handles multiline input gracefully; can be used to load entire schemas from cache.\r\n * \r\n * @param delta delta from stream.\r\n * @returns true if update is warranted, false otherwise.\r\n */\r\n addDelta(delta: string) {\r\n this.buffer += delta;\r\n const split = this.buffer.split(\"\\n\")\r\n if (split.length > 1) {\r\n split.slice(0, split.length - 1).forEach((line) => this.handleLine(line));\r\n this.buffer = split[split.length - 1];\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Parses a single line (full JSON object) and updates schema.\r\n * Generally should not be used when streaming data.\r\n */\r\n handleLine(line: string) {\r\n try {\r\n const node: SchemaNode = JSON.parse(line);\r\n\r\n const { childrenMap, componentMap } = this.schema;\r\n\r\n componentMap[node.id] = node;\r\n if (node.parentId === null) {\r\n this.schema.root = node;\r\n } else {\r\n if (!childrenMap[node.parentId]) childrenMap[node.parentId] = []\r\n childrenMap[node.parentId].push(node.id)\r\n }\r\n } catch (err) { /* probably markdown or generation inconsistency */ }\r\n }\r\n\r\n /**\r\n * Clears the buffer and handles any remaining information within.\r\n */\r\n finish(){\r\n this.handleLine(this.buffer);\r\n this.buffer = \"\";\r\n }\r\n}"],"mappings":"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","names":["readStreamableValue","useEffect","useReducer","useRef","Fragment","jsx","createElement","resolvePath","obj","path","acc","curr","get","global","local","blacklistedProps","resolveProps","props","actions","action","resolvedArgs","arg","e","resolved","key","val","renderContent","content","Renderer","_a","_b","id","componentMap","childrenMap","allowedComponents","element","sourceArrPath","sourceArr","childrenArr","childId","index","item","index1","Component","componentProps","contentNode","childNodes","nodesToRender","node","ResponseParser","delta","split","line","node","childrenMap","componentMap","Fragment","jsx","GeneratedClient","value","allowedComponents","inputStream","placeholder","actions","_a","forceUpdate","useReducer","x","parser","useRef","useEffect","ResponseParser","delta","readStreamableValue","schema","Renderer"]}
|
package/dist/metafile-esm.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/types.ts":{"bytes":683,"imports":[],"format":"esm"},"src/util.ts":{"bytes":3487,"imports":[{"path":"./templates/GeneratedUI","kind":"import-statement","external":true},{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/ResponseParser.ts":{"bytes":1865,"imports":[{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":84,"imports":[{"path":"src/types.ts","kind":"import-statement","original":"./types"},{"path":"src/util.ts","kind":"import-statement","original":"./util"},{"path":"src/ResponseParser.ts","kind":"import-statement","original":"./ResponseParser"}],"format":"esm"},"src/client/Renderer.tsx":{"bytes":
|
|
1
|
+
{"inputs":{"src/types.ts":{"bytes":683,"imports":[],"format":"esm"},"src/util.ts":{"bytes":3487,"imports":[{"path":"./templates/GeneratedUI","kind":"import-statement","external":true},{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/ResponseParser.ts":{"bytes":1865,"imports":[{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":84,"imports":[{"path":"src/types.ts","kind":"import-statement","original":"./types"},{"path":"src/util.ts","kind":"import-statement","original":"./util"},{"path":"src/ResponseParser.ts","kind":"import-statement","original":"./ResponseParser"}],"format":"esm"},"src/client/Renderer.tsx":{"bytes":4350,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"../types","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/client/GeneratedClient.tsx":{"bytes":1681,"imports":[{"path":"@ai-sdk/rsc","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./Renderer"},{"path":"src/ResponseParser.ts","kind":"import-statement","original":"../ResponseParser"},{"path":"src/types","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/client.ts":{"bytes":92,"imports":[{"path":"src/client/GeneratedClient.tsx","kind":"import-statement","original":"./client/GeneratedClient"},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./client/Renderer"}],"format":"esm"},"src/bin/cli_util.mjs":{"bytes":115,"imports":[{"path":"chalk","kind":"import-statement","external":true}],"format":"esm"},"src/bin/commands/init.mjs":{"bytes":3700,"imports":[{"path":"commander","kind":"import-statement","external":true},{"path":"fs-extra","kind":"import-statement","external":true},{"path":"path","kind":"import-statement","external":true},{"path":"child_process","kind":"import-statement","external":true},{"path":"prompts","kind":"import-statement","external":true},{"path":"chalk","kind":"import-statement","external":true},{"path":"src/bin/cli_util.mjs","kind":"import-statement","original":"../cli_util.mjs"},{"path":"url","kind":"import-statement","external":true}],"format":"esm"},"src/bin/commands/generate.mjs":{"bytes":2933,"imports":[{"path":"commander","kind":"import-statement","external":true},{"path":"path","kind":"import-statement","external":true},{"path":"react-docgen-typescript","kind":"import-statement","external":true},{"path":"prompts","kind":"import-statement","external":true},{"path":"chalk","kind":"import-statement","external":true},{"path":"fs-extra","kind":"import-statement","external":true},{"path":"src/bin/cli_util.mjs","kind":"import-statement","original":"../cli_util.mjs"}],"format":"esm"},"src/bin/cli.mjs":{"bytes":482,"imports":[{"path":"commander","kind":"import-statement","external":true},{"path":"src/bin/commands/init.mjs","kind":"import-statement","original":"./commands/init.mjs"},{"path":"src/bin/commands/generate.mjs","kind":"import-statement","original":"./commands/generate.mjs"}],"format":"esm"}},"outputs":{"dist/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":8268},"dist/index.mjs":{"imports":[],"exports":["ResponseParser","constructInput","create_skeleton","defineTool","generateComponentMap"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0},"src/util.ts":{"bytesInOutput":1050},"src/ResponseParser.ts":{"bytesInOutput":485}},"bytes":1647},"dist/client.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":13364},"dist/client.mjs":{"imports":[{"path":"@ai-sdk/rsc","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["GeneratedClient","Renderer"],"entryPoint":"src/client.ts","inputs":{"src/client/GeneratedClient.tsx":{"bytesInOutput":675},"src/client/Renderer.tsx":{"bytesInOutput":1393},"src/ResponseParser.ts":{"bytesInOutput":485},"src/client.ts":{"bytesInOutput":0}},"bytes":2611},"dist/bin/cli.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":12417},"dist/bin/cli.mjs":{"imports":[{"path":"commander","kind":"import-statement","external":true},{"path":"commander","kind":"import-statement","external":true},{"path":"fs-extra","kind":"import-statement","external":true},{"path":"path","kind":"import-statement","external":true},{"path":"child_process","kind":"import-statement","external":true},{"path":"prompts","kind":"import-statement","external":true},{"path":"chalk","kind":"import-statement","external":true},{"path":"chalk","kind":"import-statement","external":true},{"path":"url","kind":"import-statement","external":true},{"path":"commander","kind":"import-statement","external":true},{"path":"path","kind":"import-statement","external":true},{"path":"react-docgen-typescript","kind":"import-statement","external":true},{"path":"prompts","kind":"import-statement","external":true},{"path":"chalk","kind":"import-statement","external":true},{"path":"fs-extra","kind":"import-statement","external":true}],"exports":[],"entryPoint":"src/bin/cli.mjs","inputs":{"src/bin/cli.mjs":{"bytesInOutput":250},"src/bin/commands/init.mjs":{"bytesInOutput":1851},"src/bin/cli_util.mjs":{"bytesInOutput":78},"src/bin/commands/generate.mjs":{"bytesInOutput":1443}},"bytes":3643}}}
|