getsyntux 0.9.1 → 1.0.0-alpha
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/dist/{GeneratedUI-CEQN2CuA.d.mts → GeneratedUI-DuK2vD5g.d.mts} +2 -2
- package/dist/bin/cli.d.mts +6 -203
- package/dist/bin/cli.mjs +1 -1
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/client.d.mts +4 -4
- package/dist/client.mjs +6 -6
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/metafile-esm.json +1 -1
- package/package.json +10 -9
|
@@ -56,7 +56,7 @@ interface GeneratedUIProps {
|
|
|
56
56
|
cached?: string;
|
|
57
57
|
onGenerate?: (schema: string) => void;
|
|
58
58
|
skeletonize?: boolean;
|
|
59
|
-
|
|
59
|
+
onError?: (error: unknown) => void;
|
|
60
60
|
animate?: AnimateOptions;
|
|
61
61
|
rerenderEndpoint?: string;
|
|
62
62
|
onUpdate?: (schema: string) => void;
|
|
@@ -72,7 +72,7 @@ interface GeneratedUIProps {
|
|
|
72
72
|
* @param hint Custom instructions for the LLM.
|
|
73
73
|
* @param components List of allowed components that the LLM can use.
|
|
74
74
|
* @param placeholder Element to be displayed whilst awaiting streaming to begin.
|
|
75
|
-
* @param
|
|
75
|
+
* @param onError Callback if an error occurs.
|
|
76
76
|
* @param animate configuration for on-mount animation
|
|
77
77
|
* @param rerenderEndpoint The relative URL endpoint for regeneration.
|
|
78
78
|
*
|
package/dist/bin/cli.d.mts
CHANGED
|
@@ -1,205 +1,8 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import path, { dirname } from 'path';
|
|
5
|
-
import { execSync } from 'child_process';
|
|
6
|
-
import prompts from 'prompts';
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
import { fileURLToPath } from 'url';
|
|
9
|
-
import { withCustomConfig } from 'react-docgen-typescript';
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const args = process.argv.slice(2);
|
|
3
|
+
const suffix = args.length > 0 ? ` ${args.join(" ")}` : "";
|
|
10
4
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
5
|
+
console.error("getsyntux: the CLI has moved to @getsyntux/cli.");
|
|
6
|
+
console.error(`getsyntux: use: npx @getsyntux/cli${suffix}`);
|
|
14
7
|
|
|
15
|
-
|
|
16
|
-
* initialization command
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const initCommand = new Command("init").description("Initialize the project").action(async () => {
|
|
21
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
-
const __dirname = dirname(__filename);
|
|
23
|
-
|
|
24
|
-
function getPackageManager(root) {
|
|
25
|
-
if (fs.existsSync(path.join(root, 'yarn.lock'))) return 'yarn';
|
|
26
|
-
if (fs.existsSync(path.join(root, 'pnpm-lock.yaml'))) return 'pnpm';
|
|
27
|
-
return 'npm';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getInstallCommand(manager) {
|
|
31
|
-
if (manager === "yarn") return "yarn add getsyntux";
|
|
32
|
-
if (manager === "pnpm") return "pnpm add getsyntux";
|
|
33
|
-
return "npm install getsyntux";
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* verifying
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
const userRoot = process.cwd();
|
|
41
|
-
const packageJsonPath = path.join(userRoot, 'package.json');
|
|
42
|
-
|
|
43
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
44
|
-
log(chalk.red('Failed to find package.json. Run this command from your project root.'));
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* installing
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
53
|
-
const allDeps = {
|
|
54
|
-
...packageJson.dependencies,
|
|
55
|
-
...packageJson.devDependencies
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
if (allDeps['getsyntux']) {
|
|
59
|
-
log('library has already been installed. Continuing...');
|
|
60
|
-
} else {
|
|
61
|
-
log('library not detected in package.json. Please install to continue...');
|
|
62
|
-
const packageManager = getPackageManager(userRoot);
|
|
63
|
-
const command = getInstallCommand(packageManager);
|
|
64
|
-
const response = await prompts({
|
|
65
|
-
type: 'select',
|
|
66
|
-
name: 'install',
|
|
67
|
-
message: `Run ${command}?`,
|
|
68
|
-
choices: [{ title: 'Yes' }, { title: 'No' }],
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
if (response.install !== 0) {
|
|
72
|
-
log('installation cancelled.');
|
|
73
|
-
process.exit(0);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
execSync(command, { stdio: 'inherit' });
|
|
78
|
-
log('installed from ' + chalk.green(packageManager) + ' successfully.');
|
|
79
|
-
} catch (error) {
|
|
80
|
-
log('installation ' + chalk.red('failed') + ' from ' + packageManager + '.');
|
|
81
|
-
process.exit(1);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* copying
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
const templateDir = path.resolve(__dirname, '../templates');
|
|
90
|
-
const targetDir = path.resolve(process.cwd(), 'lib/getsyntux');
|
|
91
|
-
|
|
92
|
-
if (!fs.existsSync(templateDir)) {
|
|
93
|
-
log(chalk.red("failed to find template directory. This is not your fault."));
|
|
94
|
-
process.exit(1);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
log('generating files...');
|
|
98
|
-
|
|
99
|
-
if (fs.existsSync(targetDir)) {
|
|
100
|
-
const files = fs.readdirSync(targetDir);
|
|
101
|
-
if (files.length > 0) {
|
|
102
|
-
log('target directory lib/getsyntux already contains files.');
|
|
103
|
-
const response = await prompts({
|
|
104
|
-
type: 'select',
|
|
105
|
-
name: 'copy',
|
|
106
|
-
message: `Empty directory?`,
|
|
107
|
-
choices: [{ title: 'Yes' }, { title: 'No' }],
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
if (response.copy !== 0) {
|
|
111
|
-
log('installation cancelled.');
|
|
112
|
-
process.exit(0);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
fs.emptyDirSync(targetDir);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
fs.copySync(templateDir, targetDir, {
|
|
120
|
-
overwrite: true,
|
|
121
|
-
errorOnExist: false
|
|
122
|
-
});
|
|
123
|
-
log(chalk.green('installation complete.'));
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* schema generation command
|
|
128
|
-
*/
|
|
129
|
-
|
|
130
|
-
const generateDefsCommand = new Command("generate-defs").description("Generate a definition for a component")
|
|
131
|
-
.argument('<path>', 'path to component file')
|
|
132
|
-
.action(async (rawPath) => {
|
|
133
|
-
const userRoot = process.cwd();
|
|
134
|
-
const tsConfigPath = path.join(userRoot, "tsconfig.json");
|
|
135
|
-
|
|
136
|
-
const parser = withCustomConfig(tsConfigPath, {
|
|
137
|
-
shouldExtractLiteralValuesFromEnum: true,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const filePath = path.resolve(rawPath);
|
|
141
|
-
|
|
142
|
-
if (!fs.existsSync(filePath)) {
|
|
143
|
-
log('file [' + filePath + '] ' + chalk.red('not found.'));
|
|
144
|
-
process.exit(1);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
log('parsing file...');
|
|
148
|
-
const docs = parser.parse(filePath);
|
|
149
|
-
|
|
150
|
-
if (docs.length == 0) {
|
|
151
|
-
log('there are no components with props in that file. Stopping now.');
|
|
152
|
-
process.exit(0);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
log(`found ${docs.length} component(s) with prop definitions [${docs.map(e => e.displayName).join(', ')}]`);
|
|
156
|
-
|
|
157
|
-
function generatePropSignature(props) {
|
|
158
|
-
const signature = Object.entries(props).map(([key, value]) => {
|
|
159
|
-
return `${key}${value.required ? '' : '?'}: ${value.type.name}`
|
|
160
|
-
}).join(', ');
|
|
161
|
-
|
|
162
|
-
if (!signature) return '{}' // usually for class components
|
|
163
|
-
return '{ ' + signature + ' }';
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const userContexts = [];
|
|
167
|
-
|
|
168
|
-
let index = 0;
|
|
169
|
-
for (const component of docs) {
|
|
170
|
-
log(chalk.bold(`component #${index + 1}`) + ": " + component.displayName);
|
|
171
|
-
const response = await prompts({
|
|
172
|
-
type: 'text',
|
|
173
|
-
name: 'userContext',
|
|
174
|
-
message: 'What does this component do? (optional)'
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
userContexts.push(response.userContext.replaceAll('"', '\\"'));
|
|
178
|
-
index++;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function generateSignature(component, props, userContext) {
|
|
182
|
-
if (!userContext) {
|
|
183
|
-
return `{ name: "${component.displayName}", props: "${props}", component: ${component.displayName} }`;
|
|
184
|
-
} else {
|
|
185
|
-
return `{ name: "${component.displayName}", props: "${props}", component: ${component.displayName}, context: "${userContext}" }`;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
console.log();
|
|
190
|
-
log('generated definitions (safe to copy & paste directly):');
|
|
191
|
-
docs.forEach((component, index) => {
|
|
192
|
-
const props = generatePropSignature(component.props);
|
|
193
|
-
console.log(generateSignature(component, props, userContexts[index]) + ", ");
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
const program = new Command();
|
|
198
|
-
program.name("getsyntux").description("The declarative generative-UI library.");
|
|
199
|
-
program.addCommand(initCommand);
|
|
200
|
-
program.addCommand(generateDefsCommand);
|
|
201
|
-
|
|
202
|
-
const args = process.argv.slice(2);
|
|
203
|
-
if(args.length === 0) process.argv.splice(2, 0, "init");
|
|
204
|
-
|
|
205
|
-
program.parse(process.argv);
|
|
8
|
+
process.exit(1);
|
package/dist/bin/cli.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
var e=process.argv.slice(2),s=e.length>0?` ${e.join(" ")}`:"";console.error("getsyntux: the CLI has moved to @getsyntux/cli.");console.error(`getsyntux: use: npx @getsyntux/cli${s}`);process.exit(1);
|
|
3
3
|
//# sourceMappingURL=cli.mjs.map
|
package/dist/bin/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/cli.mjs","../../src/bin/commands/init.mjs","../../src/bin/cli_util.mjs","../../src/bin/commands/generate.mjs"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Command } from \"commander\";\r\nimport initCommand from \"./commands/init.mjs\";\r\nimport generateDefsCommand from \"./commands/generate.mjs\";\r\n\r\nconst program = new Command();\r\nprogram.name(\"getsyntux\").description(\"The declarative generative-UI library.\")\r\nprogram.addCommand(initCommand)\r\nprogram.addCommand(generateDefsCommand)\r\n\r\nconst args = process.argv.slice(2)\r\nif(args.length === 0) process.argv.splice(2, 0, \"init\")\r\n\r\nprogram.parse(process.argv)","/**\r\n * initialization command\r\n */\r\n\r\nimport { Command } from \"commander\";\r\n\r\nimport fs from 'fs-extra';\r\nimport path, { dirname } from 'path';\r\nimport { execSync } from 'child_process';\r\nimport prompts from 'prompts';\r\nimport chalk from 'chalk';\r\n\r\nimport { log } from \"../cli_util.mjs\";\r\n\r\nimport { fileURLToPath } from 'url';\r\n\r\nconst initCommand = new Command(\"init\").description(\"Initialize the project\").action(async () => {\r\n const __filename = fileURLToPath(import.meta.url);\r\n const __dirname = dirname(__filename);\r\n\r\n function getPackageManager(root) {\r\n if (fs.existsSync(path.join(root, 'yarn.lock'))) return 'yarn';\r\n if (fs.existsSync(path.join(root, 'pnpm-lock.yaml'))) return 'pnpm';\r\n return 'npm';\r\n }\r\n\r\n function getInstallCommand(manager) {\r\n if (manager === \"yarn\") return \"yarn add getsyntux\";\r\n if (manager === \"pnpm\") return \"pnpm add getsyntux\";\r\n return \"npm install getsyntux\";\r\n }\r\n\r\n /**\r\n * verifying\r\n */\r\n\r\n const userRoot = process.cwd();\r\n const packageJsonPath = path.join(userRoot, 'package.json');\r\n\r\n if (!fs.existsSync(packageJsonPath)) {\r\n log(chalk.red('Failed to find package.json. Run this command from your project root.'));\r\n process.exit(1);\r\n }\r\n\r\n /**\r\n * installing\r\n */\r\n\r\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\r\n const allDeps = {\r\n ...packageJson.dependencies,\r\n ...packageJson.devDependencies\r\n };\r\n\r\n if (allDeps['getsyntux']) {\r\n log('library has already been installed. Continuing...');\r\n } else {\r\n log('library not detected in package.json. Please install to continue...');\r\n const packageManager = getPackageManager(userRoot);\r\n const command = getInstallCommand(packageManager);\r\n const response = await prompts({\r\n type: 'select',\r\n name: 'install',\r\n message: `Run ${command}?`,\r\n choices: [{ title: 'Yes' }, { title: 'No' }],\r\n })\r\n\r\n if (response.install !== 0) {\r\n log('installation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n try {\r\n execSync(command, { stdio: 'inherit' });\r\n log('installed from ' + chalk.green(packageManager) + ' successfully.');\r\n } catch (error) {\r\n log('installation ' + chalk.red('failed') + ' from ' + packageManager + '.');\r\n process.exit(1);\r\n }\r\n }\r\n\r\n /**\r\n * copying\r\n */\r\n\r\n const templateDir = path.resolve(__dirname, '../templates')\r\n const targetDir = path.resolve(process.cwd(), 'lib/getsyntux');\r\n\r\n if (!fs.existsSync(templateDir)) {\r\n log(chalk.red(\"failed to find template directory. This is not your fault.\"));\r\n process.exit(1);\r\n }\r\n\r\n log('generating files...');\r\n\r\n if (fs.existsSync(targetDir)) {\r\n const files = fs.readdirSync(targetDir);\r\n if (files.length > 0) {\r\n log('target directory lib/getsyntux already contains files.');\r\n const response = await prompts({\r\n type: 'select',\r\n name: 'copy',\r\n message: `Empty directory?`,\r\n choices: [{ title: 'Yes' }, { title: 'No' }],\r\n })\r\n\r\n if (response.copy !== 0) {\r\n log('installation cancelled.');\r\n process.exit(0);\r\n }\r\n\r\n fs.emptyDirSync(targetDir);\r\n }\r\n }\r\n\r\n fs.copySync(templateDir, targetDir, {\r\n overwrite: true,\r\n errorOnExist: false\r\n })\r\n log(chalk.green('installation complete.'));\r\n})\r\n\r\nexport default initCommand;","import chalk from \"chalk\";\r\n\r\nexport function log(msg){\r\n console.log(chalk.magenta('getsyntux') + ': '+ msg)\r\n}","/**\r\n * schema generation command\r\n*/\r\nimport { Command } from \"commander\";\r\n\r\nimport path from \"path\";\r\nimport { withCustomConfig } from \"react-docgen-typescript\";\r\n\r\nimport prompts from 'prompts';\r\nimport chalk from 'chalk';\r\nimport fs from 'fs-extra';\r\n\r\nimport { log } from \"../cli_util.mjs\";\r\n\r\nconst generateDefsCommand = new Command(\"generate-defs\").description(\"Generate a definition for a component\")\r\n .argument('<path>', 'path to component file')\r\n .action(async (rawPath) => {\r\n const userRoot = process.cwd()\r\n const tsConfigPath = path.join(userRoot, \"tsconfig.json\")\r\n\r\n const parser = withCustomConfig(tsConfigPath, {\r\n shouldExtractLiteralValuesFromEnum: true,\r\n })\r\n\r\n const filePath = path.resolve(rawPath);\r\n\r\n if (!fs.existsSync(filePath)) {\r\n log('file [' + filePath + '] ' + chalk.red('not found.'))\r\n process.exit(1)\r\n }\r\n\r\n log('parsing file...')\r\n const docs = parser.parse(filePath);\r\n\r\n if (docs.length == 0) {\r\n log('there are no components with props in that file. Stopping now.')\r\n process.exit(0)\r\n }\r\n\r\n log(`found ${docs.length} component(s) with prop definitions [${docs.map(e => e.displayName).join(', ')}]`)\r\n\r\n function generatePropSignature(props) {\r\n const signature = Object.entries(props).map(([key, value]) => {\r\n return `${key}${value.required ? '' : '?'}: ${value.type.name}`\r\n }).join(', ')\r\n\r\n if (!signature) return '{}' // usually for class components\r\n return '{ ' + signature + ' }';\r\n }\r\n\r\n const userContexts = []\r\n\r\n let index = 0;\r\n for (const component of docs) {\r\n log(chalk.bold(`component #${index + 1}`) + \": \" + component.displayName)\r\n const response = await prompts({\r\n type: 'text',\r\n name: 'userContext',\r\n message: 'What does this component do? (optional)'\r\n })\r\n\r\n userContexts.push(response.userContext.replaceAll('\"', '\\\\\"'))\r\n index++;\r\n }\r\n\r\n function generateSignature(component, props, userContext) {\r\n if (!userContext) {\r\n return `{ name: \"${component.displayName}\", props: \"${props}\", component: ${component.displayName} }`;\r\n } else {\r\n return `{ name: \"${component.displayName}\", props: \"${props}\", component: ${component.displayName}, context: \"${userContext}\" }`;\r\n }\r\n }\r\n\r\n console.log()\r\n log('generated definitions (safe to copy & paste directly):')\r\n docs.forEach((component, index) => {\r\n const props = generatePropSignature(component.props);\r\n console.log(generateSignature(component, props, userContexts[index]) + \", \");\r\n })\r\n })\r\n\r\nexport default generateDefsCommand;"],"mappings":"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","names":["Command","Command","fs","path","dirname","execSync","prompts","chalk","chalk","log","msg","fileURLToPath","initCommand","Command","__filename","__dirname","dirname","getPackageManager","root","fs","path","getInstallCommand","manager","userRoot","packageJsonPath","log","chalk","packageJson","packageManager","command","prompts","execSync","templateDir","targetDir","init_default","Command","path","withCustomConfig","prompts","chalk","fs","generateDefsCommand","Command","rawPath","userRoot","tsConfigPath","path","parser","withCustomConfig","filePath","fs","log","chalk","docs","generatePropSignature","props","signature","key","value","userContexts","index","component","response","prompts","generateSignature","userContext","generate_default","program","Command","init_default","generate_default","args"]}
|
|
1
|
+
{"version":3,"sources":["../../src/bin/cli.mjs"],"sourcesContent":["#!/usr/bin/env node\n\nconst args = process.argv.slice(2);\nconst suffix = args.length > 0 ? ` ${args.join(\" \")}` : \"\";\n\nconsole.error(\"getsyntux: the CLI has moved to @getsyntux/cli.\");\nconsole.error(`getsyntux: use: npx @getsyntux/cli${suffix}`);\n\nprocess.exit(1);\n"],"mappings":";AAEA,IAAMA,EAAO,QAAQ,KAAK,MAAM,CAAC,EAC3BC,EAASD,EAAK,OAAS,EAAI,IAAIA,EAAK,KAAK,GAAG,CAAC,GAAK,GAExD,QAAQ,MAAM,iDAAiD,EAC/D,QAAQ,MAAM,qCAAqCC,CAAM,EAAE,EAE3D,QAAQ,KAAK,CAAC","names":["args","suffix"]}
|
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-
|
|
2
|
-
export { e as GeneratedUI, G as GeneratedUIProps } from './GeneratedUI-
|
|
1
|
+
import { A as AnimateOptions, R as RerenderContext, b as ComponentMap, a as ChildrenMap, c as RerenderOptions } from './GeneratedUI-DuK2vD5g.mjs';
|
|
2
|
+
export { e as GeneratedUI, G as GeneratedUIProps } from './GeneratedUI-DuK2vD5g.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,14 +8,14 @@ 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,
|
|
11
|
+
declare function GeneratedClient({ value, allowedComponents, endpoint, fetchBody, placeholder, animate, onError, onGenerate, onUpdate, rerender, }: {
|
|
12
12
|
value: any;
|
|
13
13
|
allowedComponents: Record<string, react__default.ComponentType<any> | string>;
|
|
14
14
|
endpoint: string;
|
|
15
15
|
fetchBody: object;
|
|
16
16
|
placeholder?: JSX.Element;
|
|
17
|
-
errorFallback?: JSX.Element;
|
|
18
17
|
animate?: AnimateOptions;
|
|
18
|
+
onError?: (error: unknown) => void;
|
|
19
19
|
onGenerate?: (schema: string) => void;
|
|
20
20
|
onUpdate?: (schema: string) => void;
|
|
21
21
|
rerender: RerenderContext;
|
package/dist/client.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"use client";var
|
|
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
|
|
3
|
-
<ComponentContext>${
|
|
1
|
+
"use client";var M=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 F(t){return t.reduce((n,e)=>typeof e=="string"?(n[e]=e,n):(n[e.name]=e.component,n),{})}function q({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"),a=(s==null?void 0:s.map(i=>i.context?`${i.name} [props: ${i.props}, details: ${i.context}]`:`${i.name} [props: ${i.props}]`).join(","))||"",f=JSON.stringify(n?E(t):t);return`<AllowedComponents>${o}</AllowedComponents>
|
|
3
|
+
<ComponentContext>${a}</ComponentContext>
|
|
4
4
|
<UserContext>${r||""}</UserContext>
|
|
5
5
|
<IsSkeleton>${n.toString()}</IsSkeleton>
|
|
6
6
|
<Value>
|
|
7
|
-
${
|
|
8
|
-
</Value>`}function
|
|
7
|
+
${f}
|
|
8
|
+
</Value>`}function N(t){return q(t).split(`
|
|
9
9
|
`).slice(0,2).join(`
|
|
10
|
-
`)}function
|
|
10
|
+
`)}function E(t){return t===null?"null":typeof t!="object"?typeof t:Array.isArray(t)?t.length==0?"null":[E(t[0])]:Object.entries(t).reduce((n,[e,r])=>(n[e]=E(r),n),{})}import{useCallback as re,useEffect as oe,useMemo as ie,useReducer as se,useRef as ae,useState as B}from"react";import{Fragment as K,useEffect as Q,useState as Z}from"react";import{Fragment as L,jsx as w}from"react/jsx-runtime";import{createElement as ee}from"react";var J=(t,n)=>n==="$"?t:n.split(".").reduce((e,r)=>e==null?void 0:e[r],t),T=(t,n,e)=>e.startsWith("$item.")?(e=e.slice(6),J(n,e)):e==="$item"?n:J(t,e),k=new Set(["dangerouslySetInnerHTML"]),X=t=>t.length>2&&t.startsWith("on")&&t[2]===t[2].toUpperCase(),_=(t,n,e)=>{if(!e||typeof e!="object")return e;if("$bind"in e){let o=T(t,n,e.$bind);if(!o||typeof o!="object")return o;let s=Array.isArray(o)?[...o]:{...o};return Object.keys(s).forEach(a=>{(k.has(a)||X(a)&&typeof s[a]!="function")&&delete s[a]}),s}let r=Array.isArray(e)?[...e]:{...e};return Object.keys(r).forEach(o=>{if(k.has(o)){delete r[o];return}let s=r[o];typeof s=="object"&&(r[o]=_(t,n,s),X(o)&&typeof r[o]!="function"&&delete r[o])}),r},D=(t,n,e)=>typeof e=="object"?T(t,n,e.$bind):e;function v(t){var I,A,y;let[n,e]=Z(!1);Q(()=>{let u=requestAnimationFrame(()=>e(!0));return()=>cancelAnimationFrame(u)},[]);let{id:r,componentMap:o,childrenMap:s,global:a,local:f,allowedComponents:i,animate:l}=t,c=o[r];if(c.type==="TEXT")return w(L,{children:D(a,f,c.content)});let x=(I=c.props)==null?void 0:I.source;if(c.type==="__ForEach__"&&x){let u=T(a,f,x);if(!Array.isArray(u))return null;let h=s[c.id];return w(L,{children:h==null?void 0:h.map((P,$)=>w(K,{children:u.map((b,O)=>ee(v,{...t,id:P,local:b,key:O}))},$))})}let S=i[c.type]||c.type,p={..._(a,f,c.props)};p.style={...p.style||{}};let R=((A=p.style)==null?void 0:A.opacity)??1;p.style.opacity=n?R:0,p.style.transform=n?"translateY(0)":`translateY(${(l==null?void 0:l.offset)??10}px)`,p.style.transition=`opacity ${(l==null?void 0:l.duration)??200}ms ease-out, transform ${(l==null?void 0:l.duration)??200}ms ease-out`,p.style.willChange="opacity, transform";let C=D(a,f,c.content),d=((y=s[c.id])==null?void 0:y.map((u,h)=>w(v,{...t,id:u},h)))||[],g=[C,...d].filter(u=>u!=null);return g.length>0?w(S,{...p,children:g}):w(S,{...p})}import{createContext as te,useContext as ne}from"react";var V=te(null);function ge(){let t=ne(V);if(!t)throw new Error("useSyntux must be used inside a GeneratedUI.");return t}import{Fragment as le,jsx as j}from"react/jsx-runtime";function H({value:t,allowedComponents:n,endpoint:e,fetchBody:r,placeholder:o,animate:s,onError:a,onGenerate:f,onUpdate:i,rerender:l}){var A;let[c,x]=B(t),[,S]=se(y=>y+1,0),m=ae(null),[p,R]=B(()=>({url:e,body:r}));oe(()=>{let y=!0;return m.current=new M,(async()=>{var h,P,$;try{let b=await fetch(p.url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p.body)});if(!b.ok||!b.body)throw new Error(`HTTP ${b.status}`);let O=b.body.getReader(),z=new TextDecoder;for(;;){let{done:W,value:Y}=await O.read();if(!y||W)break;let G=z.decode(Y);m.current&&G!==void 0&&m.current.addDelta(G)&&(i==null||i(m.current.total),S())}y&&((h=m.current)==null||h.finish(),S(),i==null||i(((P=m.current)==null?void 0:P.total)??""),f==null||f((($=m.current)==null?void 0:$.total)??""))}catch(b){y&&(a==null||a(b))}})(),()=>{y=!1}},[p]);let C=(A=m.current)==null?void 0:A.schema,d=re((y,u)=>{var h;if(!u||!u.regenerate)x(y);else{if(!l.endpoint)throw new Error("No rerenderEndpoint provided. Pass rerenderEndpoint to <GeneratedUI>.");x(y),R({url:l.endpoint,body:{context:l.context,existing:((h=m.current)==null?void 0:h.total)??"",hint:u.hint}})}},[l.endpoint,l.context]),g=ie(()=>({value:c,setValue:d}),[c,d]),I=()=>C!=null&&C.root?j(v,{id:C.root.id,componentMap:C.componentMap,childrenMap:C.childrenMap,allowedComponents:n,global:c,local:c,animate:s}):j(le,{children:o});return j(V.Provider,{value:g,children:I()})}import{Fragment as ce,jsx as U}from"react/jsx-runtime";function Te(t){let{endpoint:n,value:e,hint:r,components:o,skeletonize:s,placeholder:a,cached:f,onGenerate:i,onUpdate:l,onError:c,animate:x,rerenderEndpoint:S}=t,m=F(o||[]);if(f){let d=new M;d.addDelta(f),d.finish();let g=d.schema;return g.root?U(v,{id:g.root.id,componentMap:g.componentMap,childrenMap:g.childrenMap,allowedComponents:m,global:e,local:e,animate:x}):U(ce,{})}let p=(o||[]).map(d=>typeof d=="string"?d:{name:d.name,props:d.props,context:d.context}),R={value:e,hint:r,components:p,skeletonize:s},C=N(t);return U(H,{value:e,allowedComponents:m,endpoint:n,fetchBody:R,placeholder:a,onError:c,animate:x,onGenerate:i,onUpdate:l,rerender:{context:C,endpoint:S}})}export{H as GeneratedClient,Te as GeneratedUI,v as Renderer,V as SyntuxContext,ge as useSyntux};
|
|
11
11
|
//# sourceMappingURL=client.mjs.map
|
package/dist/client.mjs.map
CHANGED
|
@@ -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 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"]}
|
|
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 animate,\r\n onError,\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 animate?: AnimateOptions;\r\n onError?: (error: unknown) => void;\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\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\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: unknown) {\r\n if (isActive) onError?.(err);\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 (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 onError?: (error: unknown) => void;\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 onError Callback 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 onError,\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 onError={onError}\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","animate","onError","onGenerate","onUpdate","rerender","_a","statefulValue","setStatefulValue","useState","forceUpdate","useReducer","x","parser","useRef","fetchConfig","setFetchConfig","useEffect","isActive","ResponseParser","_b","_c","response","reader","decoder","done","delta","err","schema","modifyValue","useCallback","options","providerValue","useMemo","renderContent","Renderer","SyntuxContext","Fragment","jsx","GeneratedUI","props","endpoint","value","hint","components","skeletonize","placeholder","cached","onGenerate","onUpdate","onError","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-
|
|
2
|
-
export { A as AnimateOptions, a as ChildrenMap, b as ComponentMap, R as RerenderContext, c as RerenderOptions, d as SchemaNode } from './GeneratedUI-
|
|
1
|
+
import { C as ComponentMetadata, G as GeneratedUIProps, S as SyntuxComponent, U as UISchema } from './GeneratedUI-DuK2vD5g.mjs';
|
|
2
|
+
export { A as AnimateOptions, a as ChildrenMap, b as ComponentMap, R as RerenderContext, c as RerenderOptions, d as SchemaNode } from './GeneratedUI-DuK2vD5g.mjs';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import 'react/jsx-runtime';
|
|
5
5
|
|
package/dist/metafile-esm.json
CHANGED
|
@@ -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":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":
|
|
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":4860,"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":3606,"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.mjs":{"bytes":264,"imports":[],"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":30413},"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":1586},"src/client/Renderer.tsx":{"bytesInOutput":1997},"src/client/SyntuxContext.tsx":{"bytesInOutput":176},"src/client/GeneratedUI.tsx":{"bytesInOutput":726},"src/client.ts":{"bytesInOutput":0}},"bytes":5966},"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":586},"dist/bin/cli.mjs":{"imports":[],"exports":[],"entryPoint":"src/bin/cli.mjs","inputs":{"src/bin/cli.mjs":{"bytesInOutput":199}},"bytes":220}}}
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "getsyntux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-alpha",
|
|
4
4
|
"description": "Build generative UIs for the web.",
|
|
5
5
|
"keywords": ["generative-ui"],
|
|
6
|
+
"workspaces": [
|
|
7
|
+
"cli"
|
|
8
|
+
],
|
|
9
|
+
"bin": {
|
|
10
|
+
"getsyntux": "./dist/bin/cli.mjs"
|
|
11
|
+
},
|
|
6
12
|
"exports": {
|
|
7
13
|
".": {
|
|
8
14
|
"types": "./dist/index.d.ts",
|
|
@@ -18,11 +24,11 @@
|
|
|
18
24
|
"types": "./dist/server.d.ts",
|
|
19
25
|
"import": "./dist/server.mjs",
|
|
20
26
|
"require": "./dist/server.js"
|
|
27
|
+
},
|
|
28
|
+
"./templates/*": {
|
|
29
|
+
"default": "./dist/templates/*"
|
|
21
30
|
}
|
|
22
31
|
},
|
|
23
|
-
"bin": {
|
|
24
|
-
"getsyntux": "./dist/bin/cli.mjs"
|
|
25
|
-
},
|
|
26
32
|
"repository": {
|
|
27
33
|
"type": "git",
|
|
28
34
|
"url": "git+https://github.com/puffinsoft/syntux.git"
|
|
@@ -34,11 +40,6 @@
|
|
|
34
40
|
},
|
|
35
41
|
"homepage": "https://github.com/puffinsoft/syntux#readme",
|
|
36
42
|
"dependencies": {
|
|
37
|
-
"commander": "^14.0.2",
|
|
38
|
-
"fs-extra": "^11.3.3",
|
|
39
|
-
"prompts": "^2.4.2",
|
|
40
|
-
"chalk": "^5.6.2",
|
|
41
|
-
"react-docgen-typescript": "^2.4.0",
|
|
42
43
|
"ai": "^6.0.3"
|
|
43
44
|
},
|
|
44
45
|
"scripts": {
|