or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

code-transformation.mdcontext-integration.mdindex.mdlive-components.mdstandalone-editor.md

code-transformation.mddocs/

0

# Code Transformation

1

2

Low-level utilities for transforming and executing JSX/TypeScript code in real-time. These functions power the LiveProvider component but are also available for custom implementations and advanced use cases.

3

4

## Capabilities

5

6

### generateElement

7

8

Synchronously transforms and executes JSX code to produce a React component. This function handles the complete pipeline from raw code to executable React elements, including TypeScript compilation, JSX transformation, and safe evaluation.

9

10

```typescript { .api }

11

/**

12

* Synchronously transforms and executes JSX code to produce a React component

13

* @param options - Code transformation options

14

* @param errorCallback - Function called when transformation or execution errors occur

15

* @returns React ComponentType ready for rendering

16

*/

17

function generateElement(

18

options: {

19

/** The JSX/TypeScript code to transform and execute */

20

code: string;

21

/** Variables available in the code execution context */

22

scope?: Record<string, unknown>;

23

/** Whether to enable TypeScript transformations */

24

enableTypeScript: boolean;

25

},

26

errorCallback: (error: Error) => void

27

): ComponentType;

28

```

29

30

**Usage Examples:**

31

32

```typescript

33

import { generateElement } from "react-live";

34

35

// Basic JSX transformation

36

const simpleCode = '<h1>Hello World</h1>';

37

const SimpleComponent = generateElement(

38

{

39

code: simpleCode,

40

enableTypeScript: false

41

},

42

(error) => console.error('Generation failed:', error)

43

);

44

45

// With scope variables

46

const scopedCode = `

47

<div>

48

<Button onClick={handleClick}>

49

{buttonText}

50

</Button>

51

</div>

52

`;

53

54

const ScopedComponent = generateElement(

55

{

56

code: scopedCode,

57

scope: {

58

Button: MyButtonComponent,

59

handleClick: () => alert('Clicked!'),

60

buttonText: 'Click Me'

61

},

62

enableTypeScript: true

63

},

64

(error) => console.error('Generation failed:', error)

65

);

66

67

// TypeScript with interfaces

68

const typedCode = `

69

interface User {

70

name: string;

71

age: number;

72

}

73

74

const user: User = { name: 'Alice', age: 30 };

75

76

<div>

77

<h2>{user.name}</h2>

78

<p>Age: {user.age}</p>

79

</div>

80

`;

81

82

const TypedComponent = generateElement(

83

{

84

code: typedCode,

85

enableTypeScript: true

86

},

87

(error) => console.error('TypeScript error:', error)

88

);

89

90

// Custom error handling

91

function createComponent(code: string) {

92

let hasError = false;

93

let errorMessage = '';

94

95

const component = generateElement(

96

{ code, enableTypeScript: true },

97

(error) => {

98

hasError = true;

99

errorMessage = error.message;

100

}

101

);

102

103

return { component, hasError, errorMessage };

104

}

105

```

106

107

### renderElementAsync

108

109

Asynchronously renders code that uses the `render()` function pattern (no-inline mode). This is used for more complex scenarios where the code needs to explicitly call a render function rather than returning JSX directly.

110

111

```typescript { .api }

112

/**

113

* Asynchronously renders code that uses the render() function (no-inline mode)

114

* @param options - Code transformation options

115

* @param resultCallback - Function called with the successfully rendered component

116

* @param errorCallback - Function called when transformation or execution errors occur

117

*/

118

function renderElementAsync(

119

options: {

120

/** The code containing render() calls */

121

code: string;

122

/** Variables available in the code execution context */

123

scope?: Record<string, unknown>;

124

/** Whether to enable TypeScript transformations */

125

enableTypeScript: boolean;

126

},

127

resultCallback: (component: ComponentType) => void,

128

errorCallback: (error: Error) => void

129

): void;

130

```

131

132

**Usage Examples:**

133

134

```typescript

135

import { renderElementAsync } from "react-live";

136

137

// Basic no-inline rendering

138

const noInlineCode = `

139

function Welcome({ name }) {

140

return <h1>Hello, {name}!</h1>;

141

}

142

143

render(<Welcome name="World" />);

144

`;

145

146

renderElementAsync(

147

{

148

code: noInlineCode,

149

enableTypeScript: true

150

},

151

(component) => {

152

console.log('Component ready:', component);

153

// Use component for rendering

154

},

155

(error) => {

156

console.error('Rendering failed:', error);

157

}

158

);

159

160

// With complex component logic

161

const complexCode = `

162

function UserCard({ user }) {

163

const [expanded, setExpanded] = useState(false);

164

165

return (

166

<div className="user-card">

167

<h3>{user.name}</h3>

168

<button onClick={() => setExpanded(!expanded)}>

169

{expanded ? 'Collapse' : 'Expand'}

170

</button>

171

{expanded && (

172

<div>

173

<p>Email: {user.email}</p>

174

<p>Age: {user.age}</p>

175

</div>

176

)}

177

</div>

178

);

179

}

180

181

const sampleUser = {

182

name: 'Alice Johnson',

183

email: 'alice@example.com',

184

age: 28

185

};

186

187

render(<UserCard user={sampleUser} />);

188

`;

189

190

renderElementAsync(

191

{

192

code: complexCode,

193

scope: {

194

useState: React.useState

195

},

196

enableTypeScript: true

197

},

198

(component) => {

199

// Component with hooks ready to render

200

setCurrentComponent(component);

201

},

202

(error) => {

203

setErrorMessage(error.message);

204

}

205

);

206

207

// Multiple component rendering

208

const multiComponentCode = `

209

function Header() {

210

return <h1>My App</h1>;

211

}

212

213

function Footer() {

214

return <footer>© 2024</footer>;

215

}

216

217

function App() {

218

return (

219

<div>

220

<Header />

221

<main>

222

<p>Welcome to my application!</p>

223

</main>

224

<Footer />

225

</div>

226

);

227

}

228

229

render(<App />);

230

`;

231

232

renderElementAsync(

233

{

234

code: multiComponentCode,

235

enableTypeScript: false

236

},

237

(component) => {

238

// Multi-component app ready

239

mountComponent(component);

240

},

241

(error) => {

242

displayError(error.message);

243

}

244

);

245

246

// Error handling patterns

247

function safeRenderAsync(code: string, scope = {}) {

248

return new Promise((resolve, reject) => {

249

renderElementAsync(

250

{

251

code,

252

scope,

253

enableTypeScript: true

254

},

255

(component) => {

256

resolve(component);

257

},

258

(error) => {

259

reject(new Error(`Render failed: ${error.message}`));

260

}

261

);

262

});

263

}

264

265

// Usage with async/await

266

async function handleCodeChange(newCode: string) {

267

try {

268

const component = await safeRenderAsync(newCode, {

269

useState: React.useState,

270

useEffect: React.useEffect

271

});

272

setPreviewComponent(component);

273

} catch (error) {

274

setError(error.message);

275

}

276

}

277

```

278

279

## Transformation Pipeline

280

281

The code transformation process follows these steps:

282

283

1. **Input Validation**: Verify code is a valid string

284

2. **TypeScript Compilation**: Transform TypeScript to JavaScript (if enabled)

285

3. **JSX Transformation**: Convert JSX syntax to React.createElement calls

286

4. **Import Resolution**: Handle ES6 import statements

287

5. **Code Wrapping**: Add necessary wrapper code (for inline mode)

288

6. **Safe Evaluation**: Execute code in controlled environment with provided scope

289

7. **Error Boundary**: Wrap result in error boundary for safe rendering

290

291

## Code Execution Modes

292

293

### Inline Mode (generateElement)

294

295

- Code is automatically wrapped in a return statement

296

- Suitable for simple JSX expressions

297

- Direct evaluation and immediate component return

298

- Example: `<h1>Hello</h1>` becomes `return (<h1>Hello</h1>)`

299

300

### No-Inline Mode (renderElementAsync)

301

302

- Code must explicitly call `render()` function

303

- Suitable for complex component definitions

304

- Allows multiple component definitions before rendering

305

- Example: Code must contain `render(<MyComponent />)`

306

307

## Error Types

308

309

```typescript { .api }

310

// Common error scenarios handled by transformation functions:

311

312

// Syntax errors in JSX/TypeScript

313

SyntaxError: "Unexpected token '<'"

314

315

// Runtime errors during component execution

316

ReferenceError: "CustomComponent is not defined"

317

318

// No-inline mode specific errors

319

SyntaxError: "No-Inline evaluations must call `render`"

320

SyntaxError: "`render` must be called with valid JSX"

321

322

// Transformation errors

323

Error: "Code failed to transform"

324

```

325

326

## Advanced Usage

327

328

```typescript

329

// Custom transformation wrapper

330

function createLiveTransformer(defaultScope: Record<string, unknown>) {

331

return {

332

transformInline: (code: string, additionalScope = {}) => {

333

const scope = { ...defaultScope, ...additionalScope };

334

return generateElement({ code, scope, enableTypeScript: true }, console.error);

335

},

336

337

transformAsync: (code: string, additionalScope = {}) => {

338

const scope = { ...defaultScope, ...additionalScope };

339

return new Promise((resolve, reject) => {

340

renderElementAsync(

341

{ code, scope, enableTypeScript: true },

342

resolve,

343

reject

344

);

345

});

346

}

347

};

348

}

349

350

// Usage

351

const transformer = createLiveTransformer({

352

React,

353

useState: React.useState,

354

useEffect: React.useEffect

355

});

356

357

const InlineComponent = transformer.transformInline('<h1>Inline</h1>');

358

const AsyncComponent = await transformer.transformAsync(`

359

function App() { return <div>Async</div>; }

360

render(<App />);

361

`);

362

```