getsyntux 0.2.0 → 0.2.1

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 CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ---
8
8
 
9
- https://github.com/user-attachments/assets/f968d2c3-3b1e-4fc8-8e72-628f4361359b
9
+ https://github.com/user-attachments/assets/a930d35d-92ab-45f4-9f71-f7bc0380c4f1
10
10
 
11
11
  - ⚡ **Streamable** - display UI as you generate.
12
12
  - 🎨 **Custom Components** - maintain aesthetics and reusability.
@@ -94,20 +94,6 @@ $ npm i @ai-sdk/anthropic (if you're using Claude)
94
94
  Dynamic state generation violates the semi-deterministic paradigm of <i>syntux</i>, and is thus not supported by design.
95
95
  </details>
96
96
 
97
- <details>
98
- <summary>How do generated components share information?</summary>
99
-
100
- Use contexts.
101
-
102
- ```jsx
103
- <GeneratedPage schema={
104
- <Context.Provider>
105
- <GeneratedContent components={[ MyComponent ]} />
106
- </Context.Provider>
107
- } />
108
- ```
109
- </details>
110
-
111
97
  ---
112
98
 
113
99
  *syntux* is open source software, licensed under the [MIT](LICENSE) license.
package/dist/client.d.mts CHANGED
@@ -1,12 +1,13 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { StreamableValue } from '@ai-sdk/rsc';
3
- import react__default, { ComponentType } from 'react';
3
+ import react__default, { JSX, ComponentType } from 'react';
4
4
  import { C as ComponentMap, b as ChildrenMap } from './types-DejIW5JZ.mjs';
5
5
 
6
- declare function GeneratedClient({ value, allowedComponents, inputStream }: {
6
+ declare function GeneratedClient({ value, allowedComponents, inputStream, placeholder }: {
7
7
  value: any;
8
8
  allowedComponents: Record<string, react__default.ComponentType<any> | string>;
9
9
  inputStream: StreamableValue<string>;
10
+ placeholder?: JSX.Element;
10
11
  }): react_jsx_runtime.JSX.Element;
11
12
 
12
13
  interface RendererProps {
package/dist/client.mjs CHANGED
@@ -1,3 +1,3 @@
1
- "use client";import{readStreamableValue as x}from"@ai-sdk/rsc";import{useEffect as N,useRef as _,useState as R}from"react";import{Fragment as k}from"react";import{Fragment as S,jsx as l,jsxs as v}from"react/jsx-runtime";import{createElement as U}from"react";var b=(t,n)=>n==="$"?t:n.split(".").reduce((e,o)=>e==null?void 0:e[o],t),y=(t,n,e)=>e.startsWith("$item.")?(e=e.slice(6),b(n,e)):e==="$item"?n:b(t,e),C=(t,n,e)=>e&&("$bind"in e?y(t,n,e.$bind):(Object.keys(e).forEach(o=>{let a=e[o];typeof a=="object"&&(e[o]=C(t,n,a))}),e)),M=(t,n,e)=>typeof e=="object"?y(t,n,e.$bind):e,T=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function d(t){var g;let{id:n,componentMap:e,childrenMap:o,global:a,local:i,allowedComponents:f}=t,r=e[n];if(r.type==="TEXT")return l(S,{children:M(a,i,r.content)});let h=(g=r.props)==null?void 0:g.source;if(r.type==="__ForEach__"&&h){let p=y(a,i,h);if(!Array.isArray(p))return null;let c=o[r.id];return l(S,{children:c==null?void 0:c.map((w,P)=>l(k,{children:p.map((E,$)=>U(d,{...t,id:w,local:E,key:$}))},P))})}let s=f[r.type]||r.type,m=C(a,i,r.props);return typeof s=="string"&&T.has(s)?l(s,{...m}):v(s,{...m,children:[M(a,i,r.content),o[r.id]&&o[r.id].map((p,c)=>l(d,{...t,id:p},c))]})}var u=class{buffer="";schema={childrenMap:{},componentMap:{},root:null};addDelta(n){this.buffer+=n;let e=this.buffer.split(`
2
- `);e.length>1&&(e.slice(0,e.length-1).forEach(o=>this.handleLine(o)),this.buffer=e[e.length-1])}handleLine(n){try{let e=JSON.parse(n),{childrenMap:o,componentMap:a}=this.schema;a[e.id]=e,e.parentId===null?this.schema.root=e:(o[e.parentId]||(o[e.parentId]=[]),o[e.parentId].push(e.id))}catch{}}finish(){this.handleLine(this.buffer),this.buffer=""}};import{Fragment as A,jsx as I}from"react/jsx-runtime";function B({value:t,allowedComponents:n,inputStream:e}){let[o,a]=R(""),[i,f]=R(),r=_(null);return N(()=>{r.current||(r.current=new u),(async()=>{for await(let s of x(e))a(m=>m+s),r.current&&s!==void 0&&(r.current.addDelta(s),f(r.current.schema))})()},[e]),I(A,{children:(i==null?void 0:i.root)&&I(d,{id:i.root.id,componentMap:i.componentMap,childrenMap:i.childrenMap,allowedComponents:n,global:t,local:t})})}export{B as GeneratedClient,d as Renderer};
1
+ "use client";import{readStreamableValue as N}from"@ai-sdk/rsc";import{useEffect as _,useRef as A,useState as I}from"react";import{Fragment as T}from"react";import{Fragment as C,jsx as d,jsxs as x}from"react/jsx-runtime";import{createElement as v}from"react";var S=(t,n)=>n==="$"?t:n.split(".").reduce((e,r)=>e==null?void 0:e[r],t),g=(t,n,e)=>e.startsWith("$item.")?(e=e.slice(6),S(n,e)):e==="$item"?n:S(t,e),R=(t,n,e)=>e&&("$bind"in e?g(t,n,e.$bind):(Object.keys(e).forEach(r=>{let a=e[r];typeof a=="object"&&(e[r]=R(t,n,a))}),e)),M=(t,n,e)=>typeof e=="object"?g(t,n,e.$bind):e,U=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function h(t){var u;let{id:n,componentMap:e,childrenMap:r,global:a,local:l,allowedComponents:i}=t,o=e[n];if(o.type==="TEXT")return d(C,{children:M(a,l,o.content)});let s=(u=o.props)==null?void 0:u.source;if(o.type==="__ForEach__"&&s){let f=g(a,l,s);if(!Array.isArray(f))return null;let p=r[o.id];return d(C,{children:p==null?void 0:p.map((E,P)=>d(T,{children:f.map(($,k)=>v(h,{...t,id:E,local:$,key:k}))},P))})}let m=i[o.type]||o.type,c=R(a,l,o.props);return typeof m=="string"&&U.has(m)?d(m,{...c}):x(m,{...c,children:[M(a,l,o.content),r[o.id]&&r[o.id].map((f,p)=>d(h,{...t,id:f},p))]})}var y=class{buffer="";schema={childrenMap:{},componentMap:{},root:null};addDelta(n){this.buffer+=n;let e=this.buffer.split(`
2
+ `);e.length>1&&(e.slice(0,e.length-1).forEach(r=>this.handleLine(r)),this.buffer=e[e.length-1])}handleLine(n){try{let e=JSON.parse(n),{childrenMap:r,componentMap:a}=this.schema;a[e.id]=e,e.parentId===null?this.schema.root=e:(r[e.parentId]||(r[e.parentId]=[]),r[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 H({value:t,allowedComponents:n,inputStream:e,placeholder:r}){let[a,l]=I(""),[i,o]=I(),s=A(null);return _(()=>{s.current||(s.current=new y),(async()=>{for await(let c of N(e))l(u=>u+c),s.current&&c!==void 0&&(s.current.addDelta(c),o(s.current.schema))})()},[e]),b(w,{children:i!=null&&i.root?b(h,{id:i.root.id,componentMap:i.componentMap,childrenMap:i.childrenMap,allowedComponents:n,global:t,local:t}):b(w,{children:r})})}export{H as GeneratedClient,h as Renderer};
3
3
  //# sourceMappingURL=client.mjs.map
@@ -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, { useEffect, useRef, useState } from 'react';\r\nimport { Renderer } from './Renderer';\r\nimport { ResponseParser } from '../ResponseParser';\r\nimport { UISchema } from '../types';\r\n\r\nexport function GeneratedClient({\r\n value,\r\n allowedComponents,\r\n inputStream\r\n}: {\r\n value: any,\r\n allowedComponents: Record<string, React.ComponentType<any> | string>,\r\n inputStream: StreamableValue<string>\r\n}) {\r\n const [message, setMessage] = useState('');\r\n const [schema, setUISchema] = useState<UISchema | null>();\r\n const parser = useRef<ResponseParser | null>(null);\r\n\r\n useEffect(() => {\r\n if (!parser.current) {\r\n parser.current = new ResponseParser();\r\n }\r\n\r\n const parseStream = async () => {\r\n for await (const delta of readStreamableValue(inputStream)) {\r\n setMessage((prev) => prev + delta);\r\n if (parser.current && delta !== undefined) {\r\n parser.current.addDelta(delta);\r\n setUISchema(parser.current.schema);\r\n }\r\n }\r\n };\r\n\r\n parseStream();\r\n }, [inputStream]);\r\n\r\n return (\r\n <>\r\n {schema?.root && <Renderer id={schema.root.id} componentMap={schema.componentMap} childrenMap={schema.childrenMap} allowedComponents={allowedComponents} global={value} local={value} />}\r\n </>\r\n )\r\n}\r\n","\"use client\";\r\n\r\nimport { ComponentType, Fragment } from 'react'\r\nimport { ChildrenMap, ComponentMap, SchemaNode } from '../types';\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\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\nconst resolveProps = (global: any, local: any, props: any) => {\r\n if (!props) return props;\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);\r\n }\r\n })\r\n return props;\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}\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 function Renderer(props: RendererProps) {\r\n const {\r\n id, componentMap, childrenMap, global, local, allowedComponents\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);\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\nexport class ResponseParser {\r\n buffer = \"\";\r\n schema: UISchema = {\r\n childrenMap: {},\r\n componentMap: {},\r\n root: null\r\n }\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 }\r\n }\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 finish(){\r\n this.handleLine(this.buffer);\r\n this.buffer = \"\";\r\n }\r\n}"],"mappings":"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","names":["readStreamableValue","useEffect","useRef","useState","Fragment","jsx","jsxs","createElement","resolvePath","obj","path","acc","curr","get","global","local","resolveProps","props","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","message","setMessage","useState","schema","setUISchema","parser","useRef","useEffect","ResponseParser","delta","readStreamableValue","prev","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, useRef, useState } from 'react';\r\nimport { Renderer } from './Renderer';\r\nimport { ResponseParser } from '../ResponseParser';\r\nimport { UISchema } from '../types';\r\n\r\nexport function GeneratedClient({\r\n value,\r\n allowedComponents,\r\n inputStream,\r\n placeholder\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}) {\r\n const [message, setMessage] = useState('');\r\n const [schema, setUISchema] = useState<UISchema | null>();\r\n const parser = useRef<ResponseParser | null>(null);\r\n\r\n useEffect(() => {\r\n if (!parser.current) {\r\n parser.current = new ResponseParser();\r\n }\r\n\r\n const parseStream = async () => {\r\n for await (const delta of readStreamableValue(inputStream)) {\r\n setMessage((prev) => prev + delta);\r\n if (parser.current && delta !== undefined) {\r\n parser.current.addDelta(delta);\r\n setUISchema(parser.current.schema);\r\n }\r\n }\r\n };\r\n\r\n parseStream();\r\n }, [inputStream]);\r\n\r\n return (\r\n <>\r\n {schema?.root ? <Renderer id={schema.root.id} componentMap={schema.componentMap} childrenMap={schema.childrenMap} allowedComponents={allowedComponents} global={value} local={value} /> : <>{placeholder}</>}\r\n </>\r\n )\r\n}\r\n","\"use client\";\r\n\r\nimport { ComponentType, Fragment } from 'react'\r\nimport { ChildrenMap, ComponentMap, SchemaNode } from '../types';\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\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\nconst resolveProps = (global: any, local: any, props: any) => {\r\n if (!props) return props;\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);\r\n }\r\n })\r\n return props;\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}\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 function Renderer(props: RendererProps) {\r\n const {\r\n id, componentMap, childrenMap, global, local, allowedComponents\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);\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\nexport class ResponseParser {\r\n buffer = \"\";\r\n schema: UISchema = {\r\n childrenMap: {},\r\n componentMap: {},\r\n root: null\r\n }\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 }\r\n }\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 finish(){\r\n this.handleLine(this.buffer);\r\n this.buffer = \"\";\r\n }\r\n}"],"mappings":"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","names":["readStreamableValue","useEffect","useRef","useState","Fragment","jsx","jsxs","createElement","resolvePath","obj","path","acc","curr","get","global","local","resolveProps","props","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","message","setMessage","useState","schema","setUISchema","parser","useRef","useEffect","ResponseParser","delta","readStreamableValue","prev","Renderer"]}
@@ -1 +1 @@
1
- {"inputs":{"src/types.ts":{"bytes":583,"imports":[],"format":"esm"},"src/util.ts":{"bytes":1656,"imports":[{"path":"./templates/GeneratedUI","kind":"import-statement","external":true},{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/ResponseParser.ts":{"bytes":1163,"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":3047,"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":1373,"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":"../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.mjs":{"bytes":3494,"imports":[{"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":"url","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":4734},"dist/index.mjs":{"imports":[],"exports":["ResponseParser","constructInput","generateComponentMap"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0},"src/util.ts":{"bytesInOutput":578},"src/ResponseParser.ts":{"bytesInOutput":473}},"bytes":1126},"dist/client.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":10085},"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":572},"src/client/Renderer.tsx":{"bytesInOutput":1153},"src/ResponseParser.ts":{"bytesInOutput":473},"src/client.ts":{"bytesInOutput":0}},"bytes":2255},"dist/bin/cli.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6062},"dist/bin/cli.mjs":{"imports":[{"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":"url","kind":"import-statement","external":true}],"exports":[],"entryPoint":"src/bin/cli.mjs","inputs":{"src/bin/cli.mjs":{"bytesInOutput":2132}},"bytes":2153}}}
1
+ {"inputs":{"src/types.ts":{"bytes":583,"imports":[],"format":"esm"},"src/util.ts":{"bytes":1656,"imports":[{"path":"./templates/GeneratedUI","kind":"import-statement","external":true},{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/ResponseParser.ts":{"bytes":1163,"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":3047,"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":1444,"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":"../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.mjs":{"bytes":3494,"imports":[{"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":"url","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":4734},"dist/index.mjs":{"imports":[],"exports":["ResponseParser","constructInput","generateComponentMap"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0},"src/util.ts":{"bytesInOutput":578},"src/ResponseParser.ts":{"bytesInOutput":473}},"bytes":1126},"dist/client.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":10224},"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":595},"src/client/Renderer.tsx":{"bytesInOutput":1153},"src/ResponseParser.ts":{"bytesInOutput":473},"src/client.ts":{"bytesInOutput":0}},"bytes":2278},"dist/bin/cli.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6062},"dist/bin/cli.mjs":{"imports":[{"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":"url","kind":"import-statement","external":true}],"exports":[],"entryPoint":"src/bin/cli.mjs","inputs":{"src/bin/cli.mjs":{"bytesInOutput":2132}},"bytes":2153}}}
@@ -31,7 +31,7 @@ export interface GeneratedContentProps {
31
31
  export async function GeneratedUI(props: GeneratedContentProps) {
32
32
  const input = constructInput(props);
33
33
 
34
- const { value, model, components, cached, onGenerate } = props;
34
+ const { value, model, components, placeholder, cached, onGenerate } = props;
35
35
 
36
36
  const allowedComponents = generateComponentMap(components || []);
37
37
 
@@ -72,5 +72,5 @@ export async function GeneratedUI(props: GeneratedContentProps) {
72
72
  if(onGenerate) onGenerate(total);
73
73
  })()
74
74
 
75
- return <GeneratedClient value={value} allowedComponents={allowedComponents} inputStream={stream.value} />
75
+ return <GeneratedClient value={value} allowedComponents={allowedComponents} inputStream={stream.value} placeholder={placeholder} />
76
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getsyntux",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "The declarative generative-UI library.",
5
5
  "exports": {
6
6
  ".": {