getsyntux 0.9.0-alpha → 0.9.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
@@ -10,9 +10,7 @@ You give it a <code>value</code> and it designs the UI to display it.
10
10
 
11
11
  ---
12
12
 
13
- ![](https://raw.githubusercontent.com/puffinsoft/syntux/HEAD/docs/images/features.png)
14
-
15
- https://github.com/user-attachments/assets/c85de55d-21f3-43ff-8bd3-d6ede2171447
13
+ https://github.com/user-attachments/assets/6c94f914-6217-45d9-ad17-0c2b568d1b4b
16
14
 
17
15
  ### Features
18
16
 
@@ -59,6 +59,7 @@ interface GeneratedUIProps {
59
59
  errorFallback?: JSX.Element;
60
60
  animate?: AnimateOptions;
61
61
  rerenderEndpoint?: string;
62
+ onUpdate?: (schema: string) => void;
62
63
  }
63
64
  /**
64
65
  * Section of user interface for LLM to generate.
package/dist/client.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AnimateOptions, R as RerenderContext, b as ComponentMap, a as ChildrenMap, c as RerenderOptions } from './GeneratedUI-DFOjlyg6.mjs';
2
- export { e as GeneratedUI, G as GeneratedUIProps } from './GeneratedUI-DFOjlyg6.mjs';
1
+ import { A as AnimateOptions, R as RerenderContext, b as ComponentMap, a as ChildrenMap, c as RerenderOptions } from './GeneratedUI-CEQN2CuA.mjs';
2
+ export { e as GeneratedUI, G as GeneratedUIProps } from './GeneratedUI-CEQN2CuA.mjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import react__default, { JSX, ComponentType } from 'react';
@@ -8,7 +8,7 @@ import react__default, { JSX, ComponentType } from 'react';
8
8
  * Internal client component that handles streaming, parsing, and rendering.
9
9
  * For most use cases, use GeneratedUI instead.
10
10
  */
11
- declare function GeneratedClient({ value, allowedComponents, endpoint, fetchBody, placeholder, errorFallback, animate, onGenerate, rerender, }: {
11
+ declare function GeneratedClient({ value, allowedComponents, endpoint, fetchBody, placeholder, errorFallback, animate, onGenerate, onUpdate, rerender, }: {
12
12
  value: any;
13
13
  allowedComponents: Record<string, react__default.ComponentType<any> | string>;
14
14
  endpoint: string;
@@ -17,6 +17,7 @@ declare function GeneratedClient({ value, allowedComponents, endpoint, fetchBody
17
17
  errorFallback?: JSX.Element;
18
18
  animate?: AnimateOptions;
19
19
  onGenerate?: (schema: string) => void;
20
+ onUpdate?: (schema: string) => void;
20
21
  rerender: RerenderContext;
21
22
  }): react_jsx_runtime.JSX.Element;
22
23
 
package/dist/client.mjs CHANGED
@@ -1,11 +1,11 @@
1
- "use client";var S=class{buffer="";total="";schema={childrenMap:{},componentMap:{},root:null};addDelta(n){this.total+=n,this.buffer+=n;let e=this.buffer.split(`
2
- `);return e.length>1?(e.slice(0,e.length-1).forEach(r=>this.handleLine(r)),this.buffer=e[e.length-1],!0):!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=""}};function j(t){return t.reduce((n,e)=>typeof e=="string"?(n[e]=e,n):(n[e.name]=e.component,n),{})}function K({value:t,skeletonize:n=!1,components:e,hint:r}){let a=(e==null?void 0:e.map(o=>typeof o=="string"?o:o.name).join(","))||"",m=e==null?void 0:e.filter(o=>typeof o!="string"),y=(m==null?void 0:m.map(o=>o.context?`${o.name} [props: ${o.props}, details: ${o.context}]`:`${o.name} [props: ${o.props}]`).join(","))||"",p=JSON.stringify(n?T(t):t);return`<AllowedComponents>${a}</AllowedComponents>
3
- <ComponentContext>${y}</ComponentContext>
1
+ "use client";var R=class{buffer="";total="";schema={childrenMap:{},componentMap:{},root:null};addDelta(n){this.total+=n,this.buffer+=n;let e=this.buffer.split(`
2
+ `);return e.length>1?(e.slice(0,e.length-1).forEach(r=>this.handleLine(r)),this.buffer=e[e.length-1],!0):!1}handleLine(n){try{let e=JSON.parse(n),{childrenMap:r,componentMap:o}=this.schema;o[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=""}};function N(t){return t.reduce((n,e)=>typeof e=="string"?(n[e]=e,n):(n[e.name]=e.component,n),{})}function Z({value:t,skeletonize:n=!1,components:e,hint:r}){let o=(e==null?void 0:e.map(i=>typeof i=="string"?i:i.name).join(","))||"",s=e==null?void 0:e.filter(i=>typeof i!="string"),c=(s==null?void 0:s.map(i=>i.context?`${i.name} [props: ${i.props}, details: ${i.context}]`:`${i.name} [props: ${i.props}]`).join(","))||"",u=JSON.stringify(n?F(t):t);return`<AllowedComponents>${o}</AllowedComponents>
3
+ <ComponentContext>${c}</ComponentContext>
4
4
  <UserContext>${r||""}</UserContext>
5
5
  <IsSkeleton>${n.toString()}</IsSkeleton>
6
6
  <Value>
7
- ${p}
8
- </Value>`}function N(t){return K(t).split(`
7
+ ${u}
8
+ </Value>`}function X(t){return Z(t).split(`
9
9
  `).slice(0,2).join(`
10
- `)}function T(t){return t===null?"null":typeof t!="object"?typeof t:Array.isArray(t)?t.length==0?"null":[T(t[0])]:Object.entries(t).reduce((n,[e,r])=>(n[e]=T(r),n),{})}import{useCallback as oe,useEffect as ie,useMemo as ae,useReducer as se,useRef as le,useState as V}from"react";import{Fragment as Q,useEffect as Z,useState as ee}from"react";import{Fragment as _,jsx as M}from"react/jsx-runtime";import{createElement as te}from"react";var X=(t,n)=>n==="$"?t:n.split(".").reduce((e,r)=>e==null?void 0:e[r],t),U=(t,n,e)=>e.startsWith("$item.")?(e=e.slice(6),X(n,e)):e==="$item"?n:X(t,e),k=new Set(["dangerouslySetInnerHTML"]),D=t=>t.length>2&&t.startsWith("on")&&t[2]===t[2].toUpperCase(),B=(t,n,e)=>{if(!e)return e;if("$bind"in e){let r=U(t,n,e.$bind);return Object.keys(r).forEach(a=>{(k.has(a)||D(a)&&typeof r[a]!="function")&&delete r[a]}),r}return Object.keys(e).forEach(r=>{if(k.has(r)){delete e[r];return}let a=e[r];typeof a=="object"&&(e[r]=B(t,n,a),D(r)&&typeof e[r]!="function"&&delete e[r])}),e},L=(t,n,e)=>typeof e=="object"?U(t,n,e.$bind):e;function R(t){var I,P,v;let[n,e]=ee(!1);Z(()=>{let i=requestAnimationFrame(()=>e(!0));return()=>cancelAnimationFrame(i)},[]);let{id:r,componentMap:a,childrenMap:m,global:y,local:p,allowedComponents:o,animate:s}=t,l=a[r];if(l.type==="TEXT")return M(_,{children:L(y,p,l.content)});let C=(I=l.props)==null?void 0:I.source;if(l.type==="__ForEach__"&&C){let i=U(y,p,C);if(!Array.isArray(i))return null;let h=m[l.id];return M(_,{children:h==null?void 0:h.map((x,$)=>M(Q,{children:i.map((b,A)=>te(R,{...t,id:x,local:b,key:A}))},$))})}let d=o[l.type]||l.type,c={...B(y,p,l.props)};c.style={...c.style||{}};let g=((P=c.style)==null?void 0:P.opacity)??1;c.style.opacity=n?g:0,c.style.transform=n?"translateY(0)":`translateY(${(s==null?void 0:s.offset)??10}px)`,c.style.transition=`opacity ${(s==null?void 0:s.duration)??200}ms ease-out, transform ${(s==null?void 0:s.duration)??200}ms ease-out`,c.style.willChange="opacity, transform";let u=L(y,p,l.content),f=((v=m[l.id])==null?void 0:v.map((i,h)=>M(R,{...t,id:i},h)))||[],w=[u,...f].filter(i=>i!=null);return w.length>0?M(d,{...c,children:w}):M(d,{...c})}import{createContext as ne,useContext as re}from"react";var F=ne(null);function ge(){let t=re(F);if(!t)throw new Error("useSyntux must be used inside a GeneratedUI.");return t}import{Fragment as H,jsx as O}from"react/jsx-runtime";function z({value:t,allowedComponents:n,endpoint:e,fetchBody:r,placeholder:a,errorFallback:m,animate:y,onGenerate:p,rerender:o}){var v;let[s,l]=V(t),[,C]=se(i=>i+1,0),d=le(null),[E,c]=V(!1),[g,u]=V(()=>({url:e,body:r}));ie(()=>{let i=!0;return d.current=new S,c(!1),(async()=>{var x,$;try{let b=await fetch(g.url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g.body)});if(!b.ok||!b.body)throw new Error(`HTTP ${b.status}`);let A=b.body.getReader(),W=new TextDecoder;for(;;){let{done:Y,value:q}=await A.read();if(!i||Y)break;let J=W.decode(q);d.current&&J!==void 0&&d.current.addDelta(J)&&C()}i&&((x=d.current)==null||x.finish(),C(),p==null||p((($=d.current)==null?void 0:$.total)??""))}catch{i&&c(!0)}})(),()=>{i=!1}},[g]);let f=(v=d.current)==null?void 0:v.schema,w=oe((i,h)=>{var x;if(!h||!h.regenerate)l(i);else{if(!o.endpoint)throw new Error("No rerenderEndpoint provided. Pass rerenderEndpoint to <GeneratedUI>.");l(i),u({url:o.endpoint,body:{context:o.context,existing:((x=d.current)==null?void 0:x.total)??"",hint:h.hint}})}},[o.endpoint,o.context]),I=ae(()=>({value:s,setValue:w}),[s,w]),P=()=>E&&m?O(H,{children:m}):f!=null&&f.root?O(R,{id:f.root.id,componentMap:f.componentMap,childrenMap:f.childrenMap,allowedComponents:n,global:s,local:s,animate:y}):O(H,{children:a});return O(F.Provider,{value:I,children:P()})}import{Fragment as ce,jsx as G}from"react/jsx-runtime";function Te(t){let{endpoint:n,value:e,hint:r,components:a,skeletonize:m,placeholder:y,cached:p,onGenerate:o,errorFallback:s,animate:l,rerenderEndpoint:C}=t,d=j(a||[]);if(p){let u=new S;u.addDelta(p),u.finish();let f=u.schema;return f.root?G(R,{id:f.root.id,componentMap:f.componentMap,childrenMap:f.childrenMap,allowedComponents:d,global:e,local:e,animate:l}):G(ce,{})}let E=(a||[]).map(u=>typeof u=="string"?u:{name:u.name,props:u.props,context:u.context}),c={value:e,hint:r,components:E,skeletonize:m},g=N(t);return G(z,{value:e,allowedComponents:d,endpoint:n,fetchBody:c,placeholder:y,errorFallback:s,animate:l,onGenerate:o,rerender:{context:g,endpoint:C}})}export{z as GeneratedClient,Te as GeneratedUI,R as Renderer,F as SyntuxContext,ge as useSyntux};
10
+ `)}function F(t){return t===null?"null":typeof t!="object"?typeof t:Array.isArray(t)?t.length==0?"null":[F(t[0])]:Object.entries(t).reduce((n,[e,r])=>(n[e]=F(r),n),{})}import{useCallback as se,useEffect as ae,useMemo as le,useReducer as ce,useRef as pe,useState as U}from"react";import{Fragment as ee,useEffect as te,useState as ne}from"react";import{Fragment as B,jsx as w}from"react/jsx-runtime";import{createElement as re}from"react";var k=(t,n)=>n==="$"?t:n.split(".").reduce((e,r)=>e==null?void 0:e[r],t),V=(t,n,e)=>e.startsWith("$item.")?(e=e.slice(6),k(n,e)):e==="$item"?n:k(t,e),D=new Set(["dangerouslySetInnerHTML"]),L=t=>t.length>2&&t.startsWith("on")&&t[2]===t[2].toUpperCase(),H=(t,n,e)=>{if(!e||typeof e!="object")return e;if("$bind"in e){let o=V(t,n,e.$bind);if(!o||typeof o!="object")return o;let s=Array.isArray(o)?[...o]:{...o};return Object.keys(s).forEach(c=>{(D.has(c)||L(c)&&typeof s[c]!="function")&&delete s[c]}),s}let r=Array.isArray(e)?[...e]:{...e};return Object.keys(r).forEach(o=>{if(D.has(o)){delete r[o];return}let s=r[o];typeof s=="object"&&(r[o]=H(t,n,s),L(o)&&typeof r[o]!="function"&&delete r[o])}),r},_=(t,n,e)=>typeof e=="object"?V(t,n,e.$bind):e;function v(t){var A,I,P;let[n,e]=ne(!1);te(()=>{let h=requestAnimationFrame(()=>e(!0));return()=>cancelAnimationFrame(h)},[]);let{id:r,componentMap:o,childrenMap:s,global:c,local:u,allowedComponents:i,animate:a}=t,l=o[r];if(l.type==="TEXT")return w(B,{children:_(c,u,l.content)});let C=(A=l.props)==null?void 0:A.source;if(l.type==="__ForEach__"&&C){let h=V(c,u,C);if(!Array.isArray(h))return null;let p=s[l.id];return w(B,{children:p==null?void 0:p.map((M,b)=>w(ee,{children:h.map(($,O)=>re(v,{...t,id:M,local:$,key:O}))},b))})}let g=i[l.type]||l.type,m={...H(c,u,l.props)};m.style={...m.style||{}};let S=((I=m.style)==null?void 0:I.opacity)??1;m.style.opacity=n?S:0,m.style.transform=n?"translateY(0)":`translateY(${(a==null?void 0:a.offset)??10}px)`,m.style.transition=`opacity ${(a==null?void 0:a.duration)??200}ms ease-out, transform ${(a==null?void 0:a.duration)??200}ms ease-out`,m.style.willChange="opacity, transform";let x=_(c,u,l.content),y=((P=s[l.id])==null?void 0:P.map((h,p)=>w(v,{...t,id:h},p)))||[],d=[x,...y].filter(h=>h!=null);return d.length>0?w(g,{...m,children:d}):w(g,{...m})}import{createContext as oe,useContext as ie}from"react";var j=oe(null);function be(){let t=ie(j);if(!t)throw new Error("useSyntux must be used inside a GeneratedUI.");return t}import{Fragment as z,jsx as T}from"react/jsx-runtime";function W({value:t,allowedComponents:n,endpoint:e,fetchBody:r,placeholder:o,errorFallback:s,animate:c,onGenerate:u,onUpdate:i,rerender:a}){var h;let[l,C]=U(t),[,g]=ce(p=>p+1,0),f=pe(null),[m,S]=U(!1),[x,y]=U(()=>({url:e,body:r}));ae(()=>{let p=!0;return f.current=new R,S(!1),(async()=>{var b,$,O;try{let E=await fetch(x.url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(x.body)});if(!E.ok||!E.body)throw new Error(`HTTP ${E.status}`);let Y=E.body.getReader(),q=new TextDecoder;for(;;){let{done:K,value:Q}=await Y.read();if(!p||K)break;let J=q.decode(Q);f.current&&J!==void 0&&f.current.addDelta(J)&&(i==null||i(f.current.total),g())}p&&((b=f.current)==null||b.finish(),g(),i==null||i((($=f.current)==null?void 0:$.total)??""),u==null||u(((O=f.current)==null?void 0:O.total)??""))}catch{p&&S(!0)}})(),()=>{p=!1}},[x]);let d=(h=f.current)==null?void 0:h.schema,A=se((p,M)=>{var b;if(!M||!M.regenerate)C(p);else{if(!a.endpoint)throw new Error("No rerenderEndpoint provided. Pass rerenderEndpoint to <GeneratedUI>.");C(p),y({url:a.endpoint,body:{context:a.context,existing:((b=f.current)==null?void 0:b.total)??"",hint:M.hint}})}},[a.endpoint,a.context]),I=le(()=>({value:l,setValue:A}),[l,A]),P=()=>m&&s?T(z,{children:s}):d!=null&&d.root?T(v,{id:d.root.id,componentMap:d.componentMap,childrenMap:d.childrenMap,allowedComponents:n,global:l,local:l,animate:c}):T(z,{children:o});return T(j.Provider,{value:I,children:P()})}import{Fragment as de,jsx as G}from"react/jsx-runtime";function Ve(t){let{endpoint:n,value:e,hint:r,components:o,skeletonize:s,placeholder:c,cached:u,onGenerate:i,onUpdate:a,errorFallback:l,animate:C,rerenderEndpoint:g}=t,f=N(o||[]);if(u){let y=new R;y.addDelta(u),y.finish();let d=y.schema;return d.root?G(v,{id:d.root.id,componentMap:d.componentMap,childrenMap:d.childrenMap,allowedComponents:f,global:e,local:e,animate:C}):G(de,{})}let m=(o||[]).map(y=>typeof y=="string"?y:{name:y.name,props:y.props,context:y.context}),S={value:e,hint:r,components:m,skeletonize:s},x=X(t);return G(W,{value:e,allowedComponents:f,endpoint:n,fetchBody:S,placeholder:c,errorFallback:l,animate:C,onGenerate:i,onUpdate:a,rerender:{context:x,endpoint:g}})}export{W as GeneratedClient,Ve as GeneratedUI,v as Renderer,j as SyntuxContext,be as useSyntux};
11
11
  //# sourceMappingURL=client.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ResponseParser.ts","../src/util.ts","../src/client/GeneratedClient.tsx","../src/client/Renderer.tsx","../src/client/SyntuxContext.tsx","../src/client/GeneratedUI.tsx"],"sourcesContent":["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 total = \"\"; // accumulator\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.total += delta;\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}","import { GeneratedUIProps } from \"./client\";\r\nimport { ComponentMetadata, SyntuxComponent } from \"./types\";\r\n\r\n/**\r\n * Converts a list of components into a dictionary for fast-retrieval\r\n * during rendering.\r\n */\r\nexport function generateComponentMap(allowedComponents: (SyntuxComponent | string)[]) {\r\n return allowedComponents.reduce((acc: Record<string, React.ComponentType<any> | string>, curr: SyntuxComponent | string) => {\r\n if (typeof curr === \"string\") {\r\n acc[curr] = curr;\r\n return acc;\r\n }\r\n\r\n acc[curr.name] = curr.component;\r\n return acc;\r\n }, {})\r\n}\r\n\r\n/**\r\n * Creates LLM input in accordance to the spec.\r\n */\r\nexport function constructInput({\r\n value, skeletonize = false, components, hint\r\n}: {\r\n value: any;\r\n components?: (ComponentMetadata | string)[];\r\n hint?: string;\r\n skeletonize?: boolean;\r\n}) {\r\n const allowedComponents = components?.map((item: ComponentMetadata | string) => {\r\n if (typeof item === \"string\") return item;\r\n return item.name;\r\n }).join(',') || \"\"\r\n\r\n const customComponents = components?.filter((item): item is ComponentMetadata => typeof item !== \"string\");\r\n const componentContext = customComponents?.map((item) => {\r\n if (!item.context) {\r\n return `${item.name} [props: ${item.props}]`\r\n } else {\r\n return `${item.name} [props: ${item.props}, details: ${item.context}]`\r\n }\r\n }).join(',') || \"\"\r\n\r\n const inputValue = JSON.stringify(skeletonize ? createSkeleton(value) : value)\r\n\r\n return `<AllowedComponents>${allowedComponents}</AllowedComponents>\\n<ComponentContext>${componentContext}</ComponentContext>\\n<UserContext>${hint || \"\"}</UserContext>\\n<IsSkeleton>${skeletonize.toString()}</IsSkeleton>\\n<Value>\\n${inputValue}\\n</Value>`\r\n}\r\n\r\n/**\r\n * Builds the AllowedComponents + ComponentContext header used as context for rerender requests.\r\n */\r\nexport function constructRerenderContext(props: GeneratedUIProps) {\r\n return constructInput(props).split('\\n').slice(0, 2).join('\\n');\r\n}\r\n\r\n/**\r\n * generates a skeleton of the input value, ideal for large arrays or untrusted input.\r\n * see the FAQ for more information: https://github.com/puffinsoft/syntux/wiki/FAQ#handling-untrusted-input--large-arrays.\r\n *\r\n * *important*: assumes arrays are non-polymorphic\r\n */\r\nexport function createSkeleton(input: any) {\r\n if (input === null) return \"null\";\r\n\r\n if (typeof input !== \"object\") return typeof input;\r\n\r\n if (Array.isArray(input)) {\r\n if (input.length == 0) {\r\n return \"null\"; // ignore this field completely\r\n } else {\r\n return [createSkeleton(input[0])]\r\n }\r\n }\r\n return Object.entries(input).reduce((acc, [key, value]) => {\r\n acc[key] = createSkeleton(value);\r\n return acc;\r\n }, {})\r\n}\r\n","\"use client\";\r\n\r\nimport React, { JSX, useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';\r\nimport { AnimateOptions, RerenderContext, RerenderOptions } from '../types';\r\nimport { ResponseParser } from '../ResponseParser';\r\nimport { Renderer } from './Renderer';\r\nimport { SyntuxContext } from './SyntuxContext';\r\n\r\n// stateful, see below\r\ntype FetchConfig = {\r\n url: string;\r\n body: object;\r\n};\r\n\r\n/**\r\n * Internal client component that handles streaming, parsing, and rendering.\r\n * For most use cases, use GeneratedUI instead.\r\n */\r\nexport function GeneratedClient({\r\n value,\r\n allowedComponents,\r\n endpoint,\r\n fetchBody,\r\n placeholder,\r\n errorFallback,\r\n animate,\r\n onGenerate,\r\n rerender,\r\n}: {\r\n value: any;\r\n allowedComponents: Record<string, React.ComponentType<any> | string>;\r\n endpoint: string;\r\n fetchBody: object;\r\n placeholder?: JSX.Element;\r\n errorFallback?: JSX.Element;\r\n animate?: AnimateOptions;\r\n onGenerate?: (schema: string) => void;\r\n rerender: RerenderContext;\r\n}) {\r\n const [statefulValue, setStatefulValue] = useState(value);\r\n const [, forceUpdate] = useReducer(x => x + 1, 0);\r\n const parser = useRef<ResponseParser | null>(null);\r\n const [errored, setErrored] = useState(false);\r\n\r\n /**\r\n * single source of truth for useEffect rerenders.\r\n * body is intentionally vague, stringified very casually later.\r\n */\r\n const [fetchConfig, setFetchConfig] = useState<FetchConfig>(() => ({ url: endpoint, body: fetchBody }));\r\n\r\n useEffect(() => {\r\n /**\r\n * flag to avoid conflicting streams from mutating UI.\r\n */\r\n let isActive = true;\r\n parser.current = new ResponseParser();\r\n setErrored(false);\r\n\r\n const initiateStream = async () => {\r\n try {\r\n const response = await fetch(fetchConfig.url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(fetchConfig.body),\r\n });\r\n\r\n if (!response.ok || !response.body) throw new Error(`HTTP ${response.status}`);\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (!isActive) break;\r\n if (done) break;\r\n\r\n const delta = decoder.decode(value);\r\n\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 if (isActive) {\r\n parser.current?.finish();\r\n forceUpdate();\r\n onGenerate?.(parser.current?.total ?? '');\r\n }\r\n } catch (err) {\r\n if (isActive) setErrored(true);\r\n }\r\n };\r\n\r\n initiateStream();\r\n return () => { isActive = false; };\r\n }, [fetchConfig]);\r\n\r\n const schema = parser.current?.schema;\r\n\r\n const modifyValue = useCallback((value: any, options?: RerenderOptions) => {\r\n if (!options || !options.regenerate) {\r\n setStatefulValue(value);\r\n } else {\r\n if (!rerender.endpoint) {\r\n throw new Error(\"No rerenderEndpoint provided. Pass rerenderEndpoint to <GeneratedUI>.\");\r\n }\r\n setStatefulValue(value);\r\n setFetchConfig({\r\n url: rerender.endpoint,\r\n body: {\r\n context: rerender.context,\r\n existing: parser.current?.total ?? '',\r\n hint: options.hint,\r\n },\r\n });\r\n }\r\n }, [rerender.endpoint, rerender.context]);\r\n\r\n const providerValue = useMemo(() => ({\r\n value: statefulValue,\r\n setValue: modifyValue,\r\n }), [statefulValue, modifyValue]);\r\n\r\n const renderContent = () => {\r\n if (errored && errorFallback) return <>{errorFallback}</>;\r\n if (schema?.root) {\r\n return <Renderer\r\n id={schema.root.id}\r\n componentMap={schema.componentMap}\r\n childrenMap={schema.childrenMap}\r\n allowedComponents={allowedComponents}\r\n global={statefulValue}\r\n local={statefulValue}\r\n animate={animate}\r\n />;\r\n }\r\n return <>{placeholder}</>;\r\n };\r\n\r\n return (\r\n <SyntuxContext.Provider value={providerValue}>\r\n {renderContent()}\r\n </SyntuxContext.Provider>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { ComponentType, Fragment, useEffect, useState } from 'react';\r\nimport { AnimateOptions, ChildrenMap, ComponentMap } 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/**\r\n * LLM hallucinations sometimes cause erroneous event handler insertion.\r\n * light detection for camelCase and on[...]\r\n */\r\nconst isEventHandlerKey = (key: string) => key.length > 2 && key.startsWith('on') && key[2] === key[2].toUpperCase();\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) => {\r\n if (!props) return props;\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) || (isEventHandlerKey(key) && typeof resolved[key] !== 'function')) {\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);\r\n if (isEventHandlerKey(key) && typeof props[key] !== 'function') {\r\n delete props[key];\r\n }\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 animate?: AnimateOptions;\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 [isVisible, setIsVisible] = useState(false);\r\n\r\n useEffect(() => {\r\n const frame = requestAnimationFrame(() => setIsVisible(true));\r\n return () => cancelAnimationFrame(frame)\r\n }, [])\r\n\r\n const {\r\n id, componentMap, childrenMap, global, local, allowedComponents, animate\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\r\n const animatedProps = {...componentProps}\r\n animatedProps.style = {...(animatedProps.style) || {}}\r\n\r\n const initialOpacity = animatedProps.style?.opacity ?? 1;\r\n animatedProps.style.opacity = isVisible ? initialOpacity : 0;\r\n animatedProps.style.transform = isVisible ? 'translateY(0)' : `translateY(${animate?.offset ?? 10}px)`;\r\n animatedProps.style.transition = `opacity ${animate?.duration ?? 200}ms ease-out, transform ${animate?.duration ?? 200}ms ease-out`;\r\n animatedProps.style.willChange = 'opacity, transform';\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 {...animatedProps}>\r\n {nodesToRender}\r\n </Component>\r\n }\r\n\r\n return <Component {...animatedProps}/>\r\n}\r\n","import { createContext, useContext } from \"react\";\r\nimport { RerenderOptions } from \"src/types\";\r\n\r\nexport type SyntuxContextType = {\r\n value: any,\r\n setValue: (value: any, options?: RerenderOptions) => void\r\n}\r\n\r\nexport const SyntuxContext = createContext<SyntuxContextType | null>(null)\r\n\r\nexport function useSyntux(){\r\n const context = useContext(SyntuxContext);\r\n if(!context) throw new Error(\"useSyntux must be used inside a GeneratedUI.\");\r\n return context;\r\n}","\"use client\";\n\nimport { JSX } from 'react';\nimport { ResponseParser } from '../ResponseParser';\nimport { AnimateOptions, ComponentMetadata, SyntuxComponent, UISchema } from '../types';\nimport { constructRerenderContext, generateComponentMap } from '../util';\nimport { GeneratedClient } from './GeneratedClient';\nimport { Renderer } from './Renderer';\n\nexport interface GeneratedUIProps {\n value: any;\n endpoint: string;\n hint?: string;\n components?: (SyntuxComponent | string)[];\n placeholder?: JSX.Element;\n cached?: string;\n onGenerate?: (schema: string) => void;\n skeletonize?: boolean;\n errorFallback?: JSX.Element;\n animate?: AnimateOptions;\n rerenderEndpoint?: string;\n}\n\n/**\n * Section of user interface for LLM to generate.\n * \n * Required:\n * @param value The value (object, primitive, or array) to be displayed.\n * @param endpoint The relative URL endpoint created with createSyntuxHandler.\n * \n * Optional:\n * @param hint Custom instructions for the LLM.\n * @param components List of allowed components that the LLM can use.\n * @param placeholder Element to be displayed whilst awaiting streaming to begin.\n * @param errorFallback Element to be displayed if an error occurs.\n * @param animate configuration for on-mount animation\n * @param rerenderEndpoint The relative URL endpoint for regeneration.\n * \n * Caching:\n * @param cached Pre-generated schema string (from onGenerate), skips API call.\n * @param onGenerate Callback which accepts the generated schema, for reuse.\n * \n * Advanced:\n * @param skeletonize compresses the value for large inputs (arrays) or untrusted input\n */\nexport function GeneratedUI(props: GeneratedUIProps) {\n const {\n endpoint,\n value,\n hint,\n components,\n skeletonize,\n placeholder,\n cached,\n onGenerate,\n errorFallback,\n animate,\n rerenderEndpoint,\n } = props;\n\n const allowedComponents = generateComponentMap(components || []);\n\n // prerender if cached\n if (cached) {\n const parser = new ResponseParser();\n parser.addDelta(cached);\n parser.finish();\n\n const schema: UISchema = parser.schema;\n\n if (schema.root) {\n return <Renderer\n id={schema.root.id}\n componentMap={schema.componentMap}\n childrenMap={schema.childrenMap}\n allowedComponents={allowedComponents}\n global={value}\n local={value}\n animate={animate}\n />;\n }\n\n return <></>; // probably bad schema\n }\n\n /**\n * serialize generation information.\n */\n const componentsMetadata: (ComponentMetadata | string)[] = (components || []).map((comp: ComponentMetadata | string) => {\n if (typeof comp === 'string') return comp;\n\n return {\n name: comp.name,\n props: comp.props,\n context: comp.context\n }\n })\n\n const fetchBody = { value, hint, components: componentsMetadata, skeletonize };\n const rerenderContext = constructRerenderContext(props);\n\n return (\n <GeneratedClient\n value={value}\n allowedComponents={allowedComponents}\n endpoint={endpoint}\n fetchBody={fetchBody}\n placeholder={placeholder}\n errorFallback={errorFallback}\n animate={animate}\n onGenerate={onGenerate}\n rerender={{ context: rerenderContext, endpoint: rerenderEndpoint }}\n />\n );\n}\n"],"mappings":"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","names":["ResponseParser","delta","split","line","node","childrenMap","componentMap","generateComponentMap","allowedComponents","acc","curr","constructInput","value","skeletonize","components","hint","item","customComponents","componentContext","inputValue","createSkeleton","constructRerenderContext","props","input","key","useCallback","useEffect","useMemo","useReducer","useRef","useState","Fragment","useEffect","useState","jsx","createElement","resolvePath","obj","path","acc","curr","get","global","local","blacklistedProps","isEventHandlerKey","key","resolveProps","props","resolved","val","renderContent","content","Renderer","_a","_b","_c","isVisible","setIsVisible","frame","id","componentMap","childrenMap","allowedComponents","animate","element","sourceArrPath","sourceArr","childrenArr","childId","index","item","index1","Component","animatedProps","initialOpacity","contentNode","childNodes","nodesToRender","node","createContext","useContext","SyntuxContext","useSyntux","context","Fragment","jsx","GeneratedClient","value","allowedComponents","endpoint","fetchBody","placeholder","errorFallback","animate","onGenerate","rerender","_a","statefulValue","setStatefulValue","useState","forceUpdate","useReducer","x","parser","useRef","errored","setErrored","fetchConfig","setFetchConfig","useEffect","isActive","ResponseParser","_b","response","reader","decoder","done","delta","schema","modifyValue","useCallback","options","providerValue","useMemo","renderContent","Renderer","SyntuxContext","Fragment","jsx","GeneratedUI","props","endpoint","value","hint","components","skeletonize","placeholder","cached","onGenerate","errorFallback","animate","rerenderEndpoint","allowedComponents","generateComponentMap","parser","ResponseParser","schema","Renderer","componentsMetadata","comp","fetchBody","rerenderContext","constructRerenderContext","GeneratedClient"]}
1
+ {"version":3,"sources":["../src/ResponseParser.ts","../src/util.ts","../src/client/GeneratedClient.tsx","../src/client/Renderer.tsx","../src/client/SyntuxContext.tsx","../src/client/GeneratedUI.tsx"],"sourcesContent":["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 total = \"\"; // accumulator\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.total += delta;\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}","import { GeneratedUIProps } from \"./client\";\r\nimport { ComponentMetadata, SyntuxComponent } from \"./types\";\r\n\r\n/**\r\n * Converts a list of components into a dictionary for fast-retrieval\r\n * during rendering.\r\n */\r\nexport function generateComponentMap(allowedComponents: (SyntuxComponent | string)[]) {\r\n return allowedComponents.reduce((acc: Record<string, React.ComponentType<any> | string>, curr: SyntuxComponent | string) => {\r\n if (typeof curr === \"string\") {\r\n acc[curr] = curr;\r\n return acc;\r\n }\r\n\r\n acc[curr.name] = curr.component;\r\n return acc;\r\n }, {})\r\n}\r\n\r\n/**\r\n * Creates LLM input in accordance to the spec.\r\n */\r\nexport function constructInput({\r\n value, skeletonize = false, components, hint\r\n}: {\r\n value: any;\r\n components?: (ComponentMetadata | string)[];\r\n hint?: string;\r\n skeletonize?: boolean;\r\n}) {\r\n const allowedComponents = components?.map((item: ComponentMetadata | string) => {\r\n if (typeof item === \"string\") return item;\r\n return item.name;\r\n }).join(',') || \"\"\r\n\r\n const customComponents = components?.filter((item): item is ComponentMetadata => typeof item !== \"string\");\r\n const componentContext = customComponents?.map((item) => {\r\n if (!item.context) {\r\n return `${item.name} [props: ${item.props}]`\r\n } else {\r\n return `${item.name} [props: ${item.props}, details: ${item.context}]`\r\n }\r\n }).join(',') || \"\"\r\n\r\n const inputValue = JSON.stringify(skeletonize ? createSkeleton(value) : value)\r\n\r\n return `<AllowedComponents>${allowedComponents}</AllowedComponents>\\n<ComponentContext>${componentContext}</ComponentContext>\\n<UserContext>${hint || \"\"}</UserContext>\\n<IsSkeleton>${skeletonize.toString()}</IsSkeleton>\\n<Value>\\n${inputValue}\\n</Value>`\r\n}\r\n\r\n/**\r\n * Builds the AllowedComponents + ComponentContext header used as context for rerender requests.\r\n */\r\nexport function constructRerenderContext(props: GeneratedUIProps) {\r\n return constructInput(props).split('\\n').slice(0, 2).join('\\n');\r\n}\r\n\r\n/**\r\n * generates a skeleton of the input value, ideal for large arrays or untrusted input.\r\n * see the FAQ for more information: https://github.com/puffinsoft/syntux/wiki/FAQ#handling-untrusted-input--large-arrays.\r\n *\r\n * *important*: assumes arrays are non-polymorphic\r\n */\r\nexport function createSkeleton(input: any) {\r\n if (input === null) return \"null\";\r\n\r\n if (typeof input !== \"object\") return typeof input;\r\n\r\n if (Array.isArray(input)) {\r\n if (input.length == 0) {\r\n return \"null\"; // ignore this field completely\r\n } else {\r\n return [createSkeleton(input[0])]\r\n }\r\n }\r\n return Object.entries(input).reduce((acc, [key, value]) => {\r\n acc[key] = createSkeleton(value);\r\n return acc;\r\n }, {})\r\n}\r\n","\"use client\";\r\n\r\nimport React, { JSX, useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';\r\nimport { AnimateOptions, RerenderContext, RerenderOptions } from '../types';\r\nimport { ResponseParser } from '../ResponseParser';\r\nimport { Renderer } from './Renderer';\r\nimport { SyntuxContext } from './SyntuxContext';\r\n\r\n// stateful, see below\r\ntype FetchConfig = {\r\n url: string;\r\n body: object;\r\n};\r\n\r\n/**\r\n * Internal client component that handles streaming, parsing, and rendering.\r\n * For most use cases, use GeneratedUI instead.\r\n */\r\nexport function GeneratedClient({\r\n value,\r\n allowedComponents,\r\n endpoint,\r\n fetchBody,\r\n placeholder,\r\n errorFallback,\r\n animate,\r\n onGenerate,\r\n onUpdate,\r\n rerender,\r\n}: {\r\n value: any;\r\n allowedComponents: Record<string, React.ComponentType<any> | string>;\r\n endpoint: string;\r\n fetchBody: object;\r\n placeholder?: JSX.Element;\r\n errorFallback?: JSX.Element;\r\n animate?: AnimateOptions;\r\n onGenerate?: (schema: string) => void;\r\n onUpdate?: (schema: string) => void;\r\n rerender: RerenderContext;\r\n}) {\r\n const [statefulValue, setStatefulValue] = useState(value);\r\n const [, forceUpdate] = useReducer(x => x + 1, 0);\r\n const parser = useRef<ResponseParser | null>(null);\r\n const [errored, setErrored] = useState(false);\r\n\r\n /**\r\n * single source of truth for useEffect rerenders.\r\n * body is intentionally vague, stringified very casually later.\r\n */\r\n const [fetchConfig, setFetchConfig] = useState<FetchConfig>(() => ({ url: endpoint, body: fetchBody }));\r\n\r\n useEffect(() => {\r\n /**\r\n * flag to avoid conflicting streams from mutating UI.\r\n */\r\n let isActive = true;\r\n parser.current = new ResponseParser();\r\n setErrored(false);\r\n\r\n const initiateStream = async () => {\r\n try {\r\n const response = await fetch(fetchConfig.url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(fetchConfig.body),\r\n });\r\n\r\n if (!response.ok || !response.body) throw new Error(`HTTP ${response.status}`);\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (!isActive) break;\r\n if (done) break;\r\n\r\n const delta = decoder.decode(value);\r\n\r\n if (parser.current && delta !== undefined) {\r\n if (parser.current.addDelta(delta)) {\r\n onUpdate?.(parser.current.total);\r\n forceUpdate();\r\n }\r\n }\r\n }\r\n\r\n if (isActive) {\r\n parser.current?.finish();\r\n forceUpdate();\r\n onUpdate?.(parser.current?.total ?? '');\r\n onGenerate?.(parser.current?.total ?? '');\r\n }\r\n } catch (err) {\r\n if (isActive) setErrored(true);\r\n }\r\n };\r\n\r\n initiateStream();\r\n return () => { isActive = false; };\r\n }, [fetchConfig]);\r\n\r\n const schema = parser.current?.schema;\r\n\r\n const modifyValue = useCallback((value: any, options?: RerenderOptions) => {\r\n if (!options || !options.regenerate) {\r\n setStatefulValue(value);\r\n } else {\r\n if (!rerender.endpoint) {\r\n throw new Error(\"No rerenderEndpoint provided. Pass rerenderEndpoint to <GeneratedUI>.\");\r\n }\r\n setStatefulValue(value);\r\n setFetchConfig({\r\n url: rerender.endpoint,\r\n body: {\r\n context: rerender.context,\r\n existing: parser.current?.total ?? '',\r\n hint: options.hint,\r\n },\r\n });\r\n }\r\n }, [rerender.endpoint, rerender.context]);\r\n\r\n const providerValue = useMemo(() => ({\r\n value: statefulValue,\r\n setValue: modifyValue,\r\n }), [statefulValue, modifyValue]);\r\n\r\n const renderContent = () => {\r\n if (errored && errorFallback) return <>{errorFallback}</>;\r\n if (schema?.root) {\r\n return <Renderer\r\n id={schema.root.id}\r\n componentMap={schema.componentMap}\r\n childrenMap={schema.childrenMap}\r\n allowedComponents={allowedComponents}\r\n global={statefulValue}\r\n local={statefulValue}\r\n animate={animate}\r\n />;\r\n }\r\n return <>{placeholder}</>;\r\n };\r\n\r\n return (\r\n <SyntuxContext.Provider value={providerValue}>\r\n {renderContent()}\r\n </SyntuxContext.Provider>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { ComponentType, Fragment, useEffect, useState } from 'react';\r\nimport { AnimateOptions, ChildrenMap, ComponentMap } 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/**\r\n * LLM hallucinations sometimes cause erroneous event handler insertion.\r\n * light detection for camelCase and on[...]\r\n */\r\nconst isEventHandlerKey = (key: string) => key.length > 2 && key.startsWith('on') && key[2] === key[2].toUpperCase();\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) => {\r\n if (!props || typeof props !== 'object') return props;\r\n\r\n if (\"$bind\" in props) { // $bind may be falsy value\r\n const resolved = get(global, local, props.$bind);\r\n\t\t\r\n\t\tif(!resolved || typeof resolved !== 'object') return resolved;\r\n\t\t\r\n\t\tconst clone = Array.isArray(resolved) ? [...resolved] : {...resolved};\r\n Object.keys(clone).forEach((key) => {\r\n if (blacklistedProps.has(key) || (isEventHandlerKey(key) && typeof clone[key] !== 'function')) {\r\n delete clone[key];\r\n }\r\n })\r\n return clone;\r\n }\r\n\t\r\n\tconst clone = Array.isArray(props) ? [...props] : {...props};\r\n Object.keys(clone).forEach((key) => {\r\n if (blacklistedProps.has(key)) {\r\n delete clone[key];\r\n return;\r\n }\r\n\r\n const val = clone[key];\r\n if (typeof val === \"object\") {\r\n clone[key] = resolveProps(global, local, val);\r\n if (isEventHandlerKey(key) && typeof clone[key] !== 'function') {\r\n delete clone[key];\r\n }\r\n }\r\n })\r\n return clone;\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 animate?: AnimateOptions;\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 [isVisible, setIsVisible] = useState(false);\r\n\r\n useEffect(() => {\r\n const frame = requestAnimationFrame(() => setIsVisible(true));\r\n return () => cancelAnimationFrame(frame)\r\n }, [])\r\n\r\n const {\r\n id, componentMap, childrenMap, global, local, allowedComponents, animate\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\r\n const animatedProps = {...componentProps}\r\n animatedProps.style = {...(animatedProps.style) || {}}\r\n\r\n const initialOpacity = animatedProps.style?.opacity ?? 1;\r\n animatedProps.style.opacity = isVisible ? initialOpacity : 0;\r\n animatedProps.style.transform = isVisible ? 'translateY(0)' : `translateY(${animate?.offset ?? 10}px)`;\r\n animatedProps.style.transition = `opacity ${animate?.duration ?? 200}ms ease-out, transform ${animate?.duration ?? 200}ms ease-out`;\r\n animatedProps.style.willChange = 'opacity, transform';\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 {...animatedProps}>\r\n {nodesToRender}\r\n </Component>\r\n }\r\n\r\n return <Component {...animatedProps}/>\r\n}\r\n","import { createContext, useContext } from \"react\";\r\nimport { RerenderOptions } from \"src/types\";\r\n\r\nexport type SyntuxContextType = {\r\n value: any,\r\n setValue: (value: any, options?: RerenderOptions) => void\r\n}\r\n\r\nexport const SyntuxContext = createContext<SyntuxContextType | null>(null)\r\n\r\nexport function useSyntux(){\r\n const context = useContext(SyntuxContext);\r\n if(!context) throw new Error(\"useSyntux must be used inside a GeneratedUI.\");\r\n return context;\r\n}","\"use client\";\n\nimport { JSX } from 'react';\nimport { ResponseParser } from '../ResponseParser';\nimport { AnimateOptions, ComponentMetadata, SyntuxComponent, UISchema } from '../types';\nimport { constructRerenderContext, generateComponentMap } from '../util';\nimport { GeneratedClient } from './GeneratedClient';\nimport { Renderer } from './Renderer';\n\nexport interface GeneratedUIProps {\n value: any;\n endpoint: string;\n hint?: string;\n components?: (SyntuxComponent | string)[];\n placeholder?: JSX.Element;\n cached?: string;\n onGenerate?: (schema: string) => void;\n skeletonize?: boolean;\n errorFallback?: JSX.Element;\n animate?: AnimateOptions;\n rerenderEndpoint?: string;\n onUpdate?: (schema: string) => void;\n}\n\n/**\n * Section of user interface for LLM to generate.\n * \n * Required:\n * @param value The value (object, primitive, or array) to be displayed.\n * @param endpoint The relative URL endpoint created with createSyntuxHandler.\n * \n * Optional:\n * @param hint Custom instructions for the LLM.\n * @param components List of allowed components that the LLM can use.\n * @param placeholder Element to be displayed whilst awaiting streaming to begin.\n * @param errorFallback Element to be displayed if an error occurs.\n * @param animate configuration for on-mount animation\n * @param rerenderEndpoint The relative URL endpoint for regeneration.\n * \n * Caching:\n * @param cached Pre-generated schema string (from onGenerate), skips API call.\n * @param onGenerate Callback which accepts the generated schema, for reuse.\n * \n * Advanced:\n * @param skeletonize compresses the value for large inputs (arrays) or untrusted input\n */\nexport function GeneratedUI(props: GeneratedUIProps) {\n const {\n endpoint,\n value,\n hint,\n components,\n skeletonize,\n placeholder,\n cached,\n onGenerate,\n onUpdate,\n errorFallback,\n animate,\n rerenderEndpoint,\n } = props;\n\n const allowedComponents = generateComponentMap(components || []);\n\n // prerender if cached\n if (cached) {\n const parser = new ResponseParser();\n parser.addDelta(cached);\n parser.finish();\n\n const schema: UISchema = parser.schema;\n\n if (schema.root) {\n return <Renderer\n id={schema.root.id}\n componentMap={schema.componentMap}\n childrenMap={schema.childrenMap}\n allowedComponents={allowedComponents}\n global={value}\n local={value}\n animate={animate}\n />;\n }\n\n return <></>; // probably bad schema\n }\n\n /**\n * serialize generation information.\n */\n const componentsMetadata: (ComponentMetadata | string)[] = (components || []).map((comp: ComponentMetadata | string) => {\n if (typeof comp === 'string') return comp;\n\n return {\n name: comp.name,\n props: comp.props,\n context: comp.context\n }\n })\n\n const fetchBody = { value, hint, components: componentsMetadata, skeletonize };\n const rerenderContext = constructRerenderContext(props);\n\n return (\n <GeneratedClient\n value={value}\n allowedComponents={allowedComponents}\n endpoint={endpoint}\n fetchBody={fetchBody}\n placeholder={placeholder}\n errorFallback={errorFallback}\n animate={animate}\n onGenerate={onGenerate}\n onUpdate={onUpdate}\n rerender={{ context: rerenderContext, endpoint: rerenderEndpoint }}\n />\n );\n}\n"],"mappings":"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","names":["ResponseParser","delta","split","line","node","childrenMap","componentMap","generateComponentMap","allowedComponents","acc","curr","constructInput","value","skeletonize","components","hint","item","customComponents","componentContext","inputValue","createSkeleton","constructRerenderContext","props","input","key","useCallback","useEffect","useMemo","useReducer","useRef","useState","Fragment","useEffect","useState","jsx","createElement","resolvePath","obj","path","acc","curr","get","global","local","blacklistedProps","isEventHandlerKey","key","resolveProps","props","resolved","clone","val","renderContent","content","Renderer","_a","_b","_c","isVisible","setIsVisible","frame","id","componentMap","childrenMap","allowedComponents","animate","element","sourceArrPath","sourceArr","childrenArr","childId","index","item","index1","Component","animatedProps","initialOpacity","contentNode","childNodes","nodesToRender","node","createContext","useContext","SyntuxContext","useSyntux","context","Fragment","jsx","GeneratedClient","value","allowedComponents","endpoint","fetchBody","placeholder","errorFallback","animate","onGenerate","onUpdate","rerender","_a","statefulValue","setStatefulValue","useState","forceUpdate","useReducer","x","parser","useRef","errored","setErrored","fetchConfig","setFetchConfig","useEffect","isActive","ResponseParser","_b","_c","response","reader","decoder","done","delta","schema","modifyValue","useCallback","options","providerValue","useMemo","renderContent","Renderer","SyntuxContext","Fragment","jsx","GeneratedUI","props","endpoint","value","hint","components","skeletonize","placeholder","cached","onGenerate","onUpdate","errorFallback","animate","rerenderEndpoint","allowedComponents","generateComponentMap","parser","ResponseParser","schema","Renderer","componentsMetadata","comp","fetchBody","rerenderContext","constructRerenderContext","GeneratedClient"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ComponentMetadata, G as GeneratedUIProps, S as SyntuxComponent, U as UISchema } from './GeneratedUI-DFOjlyg6.mjs';
2
- export { A as AnimateOptions, a as ChildrenMap, b as ComponentMap, R as RerenderContext, c as RerenderOptions, d as SchemaNode } from './GeneratedUI-DFOjlyg6.mjs';
1
+ import { C as ComponentMetadata, G as GeneratedUIProps, S as SyntuxComponent, U as UISchema } from './GeneratedUI-CEQN2CuA.mjs';
2
+ export { A as AnimateOptions, a as ChildrenMap, b as ComponentMap, R as RerenderContext, c as RerenderOptions, d as SchemaNode } from './GeneratedUI-CEQN2CuA.mjs';
3
3
  import * as react from 'react';
4
4
  import 'react/jsx-runtime';
5
5
 
@@ -1 +1 @@
1
- {"inputs":{"src/types.ts":{"bytes":1308,"imports":[],"format":"esm"},"src/util.ts":{"bytes":2873,"imports":[{"path":"./client","kind":"import-statement","external":true},{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/ResponseParser.ts":{"bytes":1923,"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":5020,"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/SyntuxContext.tsx":{"bytes":481,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/types","kind":"import-statement","external":true}],"format":"esm"},"src/client/GeneratedClient.tsx":{"bytes":4814,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"../types","kind":"import-statement","external":true},{"path":"src/ResponseParser.ts","kind":"import-statement","original":"../ResponseParser"},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./Renderer"},{"path":"src/client/SyntuxContext.tsx","kind":"import-statement","original":"./SyntuxContext"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/client/GeneratedUI.tsx":{"bytes":3547,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/ResponseParser.ts","kind":"import-statement","original":"../ResponseParser"},{"path":"../types","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/client/GeneratedClient.tsx","kind":"import-statement","original":"./GeneratedClient"},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./Renderer"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/client.ts":{"bytes":172,"imports":[{"path":"src/client/GeneratedUI.tsx","kind":"import-statement","original":"./client/GeneratedUI"},{"path":"src/client/GeneratedClient.tsx","kind":"import-statement","original":"./client/GeneratedClient"},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./client/Renderer"},{"path":"src/client/SyntuxContext.tsx","kind":"import-statement","original":"./client/SyntuxContext"}],"format":"esm"},"src/server/index.ts":{"bytes":2077,"imports":[{"path":"ai","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"}],"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":7402},"dist/index.mjs":{"imports":[],"exports":["ResponseParser","constructInput","constructRerenderContext","createSkeleton","generateComponentMap"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0},"src/util.ts":{"bytesInOutput":863},"src/ResponseParser.ts":{"bytesInOutput":508}},"bytes":1496},"dist/client.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":29788},"dist/client.mjs":{"imports":[{"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","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["GeneratedClient","GeneratedUI","Renderer","SyntuxContext","useSyntux"],"entryPoint":"src/client.ts","inputs":{"src/ResponseParser.ts":{"bytesInOutput":508},"src/util.ts":{"bytesInOutput":863},"src/client/GeneratedClient.tsx":{"bytesInOutput":1522},"src/client/Renderer.tsx":{"bytesInOutput":1870},"src/client/SyntuxContext.tsx":{"bytesInOutput":176},"src/client/GeneratedUI.tsx":{"bytesInOutput":716},"src/client.ts":{"bytesInOutput":0}},"bytes":5765},"dist/server.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":7351},"dist/server.mjs":{"imports":[{"path":"ai","kind":"import-statement","external":true}],"exports":["createSyntuxHandler","createSyntuxRerenderHandler"],"entryPoint":"src/server/index.ts","inputs":{"src/server/index.ts":{"bytesInOutput":524},"src/util.ts":{"bytesInOutput":708}},"bytes":1299},"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}}}
1
+ {"inputs":{"src/types.ts":{"bytes":1308,"imports":[],"format":"esm"},"src/util.ts":{"bytes":2873,"imports":[{"path":"./client","kind":"import-statement","external":true},{"path":"./types","kind":"import-statement","external":true}],"format":"esm"},"src/ResponseParser.ts":{"bytes":1923,"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":5250,"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/SyntuxContext.tsx":{"bytes":481,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/types","kind":"import-statement","external":true}],"format":"esm"},"src/client/GeneratedClient.tsx":{"bytes":5000,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"../types","kind":"import-statement","external":true},{"path":"src/ResponseParser.ts","kind":"import-statement","original":"../ResponseParser"},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./Renderer"},{"path":"src/client/SyntuxContext.tsx","kind":"import-statement","original":"./SyntuxContext"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/client/GeneratedUI.tsx":{"bytes":3638,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/ResponseParser.ts","kind":"import-statement","original":"../ResponseParser"},{"path":"../types","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/client/GeneratedClient.tsx","kind":"import-statement","original":"./GeneratedClient"},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./Renderer"},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"format":"esm"},"src/client.ts":{"bytes":172,"imports":[{"path":"src/client/GeneratedUI.tsx","kind":"import-statement","original":"./client/GeneratedUI"},{"path":"src/client/GeneratedClient.tsx","kind":"import-statement","original":"./client/GeneratedClient"},{"path":"src/client/Renderer.tsx","kind":"import-statement","original":"./client/Renderer"},{"path":"src/client/SyntuxContext.tsx","kind":"import-statement","original":"./client/SyntuxContext"}],"format":"esm"},"src/server/index.ts":{"bytes":2077,"imports":[{"path":"ai","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"}],"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":7402},"dist/index.mjs":{"imports":[],"exports":["ResponseParser","constructInput","constructRerenderContext","createSkeleton","generateComponentMap"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0},"src/util.ts":{"bytesInOutput":863},"src/ResponseParser.ts":{"bytesInOutput":508}},"bytes":1496},"dist/client.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30709},"dist/client.mjs":{"imports":[{"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","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true},{"path":"react/jsx-runtime","kind":"import-statement","external":true}],"exports":["GeneratedClient","GeneratedUI","Renderer","SyntuxContext","useSyntux"],"entryPoint":"src/client.ts","inputs":{"src/ResponseParser.ts":{"bytesInOutput":508},"src/util.ts":{"bytesInOutput":863},"src/client/GeneratedClient.tsx":{"bytesInOutput":1618},"src/client/Renderer.tsx":{"bytesInOutput":2003},"src/client/SyntuxContext.tsx":{"bytesInOutput":176},"src/client/GeneratedUI.tsx":{"bytesInOutput":738},"src/client.ts":{"bytesInOutput":0}},"bytes":6016},"dist/server.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":7351},"dist/server.mjs":{"imports":[{"path":"ai","kind":"import-statement","external":true}],"exports":["createSyntuxHandler","createSyntuxRerenderHandler"],"entryPoint":"src/server/index.ts","inputs":{"src/server/index.ts":{"bytesInOutput":524},"src/util.ts":{"bytesInOutput":708}},"bytes":1299},"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}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getsyntux",
3
- "version": "0.9.0-alpha",
3
+ "version": "0.9.1",
4
4
  "description": "Build generative UIs for the web.",
5
5
  "keywords": ["generative-ui"],
6
6
  "exports": {
@@ -34,8 +34,6 @@
34
34
  },
35
35
  "homepage": "https://github.com/puffinsoft/syntux#readme",
36
36
  "dependencies": {
37
- "@types/node": "^25.0.2",
38
- "@types/react": "^19.2.7",
39
37
  "commander": "^14.0.2",
40
38
  "fs-extra": "^11.3.3",
41
39
  "prompts": "^2.4.2",
@@ -52,6 +50,8 @@
52
50
  "/dist/**/*"
53
51
  ],
54
52
  "devDependencies": {
53
+ "@types/node": "^25.0.2",
54
+ "@types/react": "^19.2.7",
55
55
  "@ai-sdk/anthropic": "^3.0.1",
56
56
  "esbuild-plugin-preserve-directives": "^0.0.7",
57
57
  "tsup": "^8.5.1",