or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-client.mdcanvas-operations.mdcomponent-system.mdcomposables.mdindex.mdstate-management.mdworkflow-management.md

composables.mddocs/

0

# Composables

1

2

Vue 3 composables providing reusable functionality for canvas operations, workflow helpers, UI interactions, and common utilities.

3

4

## Capabilities

5

6

### Canvas Composables

7

8

Composables for canvas and node operations.

9

10

```typescript { .api }

11

/**

12

* Access canvas node data within node components

13

*/

14

function useCanvasNode(): UseCanvasNodeReturn;

15

16

interface UseCanvasNodeReturn {

17

node: InjectedCanvasNode;

18

id: ComputedRef<string>;

19

name: ComputedRef<string>;

20

label: ComputedRef<string>;

21

subtitle: ComputedRef<string>;

22

inputs: ComputedRef<CanvasConnectionPort[]>;

23

outputs: ComputedRef<CanvasConnectionPort[]>;

24

connections: ComputedRef<INodeConnections>;

25

isDisabled: ComputedRef<boolean>;

26

isReadOnly: ComputedRef<boolean>;

27

isSelected: ComputedRef<boolean>;

28

pinnedDataCount: ComputedRef<number>;

29

hasPinnedData: ComputedRef<boolean>;

30

runDataIterations: ComputedRef<number>;

31

runDataOutputMap: ComputedRef<Record<string, any>>;

32

hasRunData: ComputedRef<boolean>;

33

issues: ComputedRef<string[]>;

34

hasIssues: ComputedRef<boolean>;

35

executionStatus: ComputedRef<ExecutionStatus | undefined>;

36

executionWaiting: ComputedRef<string | undefined>;

37

executionWaitingForNext: ComputedRef<boolean>;

38

executionRunning: ComputedRef<boolean>;

39

render: ComputedRef<CanvasNodeRender>;

40

eventBus: ComputedRef<EventBus | undefined>;

41

}

42

43

/**

44

* Canvas operations for node manipulation

45

*/

46

function useCanvasOperations(): CanvasOperationsReturn;

47

48

interface CanvasOperationsReturn {

49

addNodes(nodes: AddedNode[], connections?: AddedNodeConnection[]): void;

50

deleteNode(id: string): void;

51

copyNodes(ids: string[]): void;

52

pasteNodes(position?: XYPosition): void;

53

createConnection(source: CanvasConnectionPort, target: CanvasConnectionPort): void;

54

updateNodePosition(id: string, position: XYPosition): void;

55

}

56

57

/**

58

* Canvas layout and arrangement

59

*/

60

function useCanvasLayout(): CanvasLayoutReturn;

61

62

interface CanvasLayoutReturn {

63

layout(target: 'all' | 'selection'): void;

64

arrangeNodes(nodes: INodeUi[], direction?: 'horizontal' | 'vertical'): INodeUi[];

65

}

66

```

67

68

### Workflow Composables

69

70

Composables for workflow operations and management.

71

72

```typescript { .api }

73

/**

74

* Workflow helper functions

75

*/

76

function useWorkflowHelpers(): WorkflowHelpersReturn;

77

78

interface WorkflowHelpersReturn {

79

getWorkflowDataToSave(): IWorkflowDataUpdate;

80

saveCurrentWorkflow(options?: { tags?: string[] }): Promise<void>;

81

getCurrentWorkflow(copyData?: boolean): Workflow;

82

initializeWorkflow(): void;

83

resolveRequiredParameters(node: INodeUi, nodeType: INodeTypeDescription): INodeParameters;

84

}

85

86

/**

87

* Workflow execution helpers

88

*/

89

function useRunWorkflow(): RunWorkflowReturn;

90

91

interface RunWorkflowReturn {

92

runWorkflowData: Ref<IStartRunData | null>;

93

isExecutionPreview: Ref<boolean>;

94

runWorkflow(data: IStartRunData): Promise<IExecutionPushResponse>;

95

stopCurrentExecution(): Promise<void>;

96

stopExecution(executionId: string): Promise<void>;

97

}

98

99

/**

100

* Workflow saving functionality

101

*/

102

function useWorkflowSaving(): WorkflowSavingReturn;

103

104

interface WorkflowSavingReturn {

105

isSaving: Ref<boolean>;

106

hasUnsavedChanges: Ref<boolean>;

107

saveWorkflow(options?: { tags?: string[]; redirect?: boolean }): Promise<void>;

108

saveAsNewWorkflow(name: string): Promise<void>;

109

}

110

```

111

112

### Node Composables

113

114

Node-specific helper composables.

115

116

```typescript { .api }

117

/**

118

* Node helper functions

119

*/

120

function useNodeHelpers(): NodeHelpersReturn;

121

122

interface NodeHelpersReturn {

123

getNodeSubtitle(node: INodeUi, nodeType?: INodeTypeDescription, workflow?: Workflow): string;

124

hasNodeCredential(node: INodeUi, credentialType: string): boolean;

125

assignNodeId(node: INodeUi): string;

126

getNodeIssues(node: INodeUi, workflow: Workflow): INodeIssues | null;

127

updateNodeParameterIssues(node: INodeUi, issues?: INodeIssues): void;

128

}

129

130

/**

131

* Node type information

132

*/

133

function useNodeType(params: { node: Ref<INodeUi | null> }): NodeTypeReturn;

134

135

interface NodeTypeReturn {

136

nodeType: ComputedRef<INodeTypeDescription | null>;

137

isSubNode: ComputedRef<boolean>;

138

isTriggerNode: ComputedRef<boolean>;

139

isConfigNode: ComputedRef<boolean>;

140

hasMultipleOutputs: ComputedRef<boolean>;

141

}

142

143

/**

144

* Node connections management

145

*/

146

function useNodeConnections(): NodeConnectionsReturn;

147

148

interface NodeConnectionsReturn {

149

getNodeConnections(nodeName: string): { input: IConnection[][]; output: IConnection[][] };

150

getChildNodes(nodeName: string): string[];

151

getParentNodes(nodeName: string): string[];

152

hasInputConnections(nodeName: string): boolean;

153

hasOutputConnections(nodeName: string): boolean;

154

}

155

```

156

157

### UI Interaction Composables

158

159

Composables for user interface interactions.

160

161

```typescript { .api }

162

/**

163

* Keyboard shortcuts management

164

*/

165

function useKeybindings(

166

keymap: MaybeRefOrGetter<KeyMap>,

167

options?: KeybindingOptions

168

): void;

169

170

interface KeyMap {

171

[key: string]: (event: KeyboardEvent) => void | boolean;

172

}

173

174

interface KeybindingOptions {

175

disabled?: MaybeRefOrGetter<boolean>;

176

preventDefault?: boolean;

177

stopPropagation?: boolean;

178

}

179

180

/**

181

* Toast notifications

182

*/

183

function useToast(): ToastReturn;

184

185

interface ToastReturn {

186

showMessage(config: NotificationOptions): void;

187

showError(error: Error | string, title?: string): void;

188

showSuccess(message: string, title?: string): void;

189

showWarning(message: string, title?: string): void;

190

showInfo(message: string, title?: string): void;

191

}

192

193

/**

194

* Loading states management

195

*/

196

function useLoadingService(): LoadingServiceReturn;

197

198

interface LoadingServiceReturn {

199

startLoading(text?: string): void;

200

stopLoading(): void;

201

setLoadingText(text: string): void;

202

}

203

204

/**

205

* Clipboard operations

206

*/

207

function useClipboard(): ClipboardReturn;

208

209

interface ClipboardReturn {

210

copy(text: string): Promise<void>;

211

paste(): Promise<string>;

212

isSupported: boolean;

213

}

214

```

215

216

### Data Management Composables

217

218

Composables for data processing and management.

219

220

```typescript { .api }

221

/**

222

* Data schema inference and handling

223

*/

224

function useDataSchema(): DataSchemaReturn;

225

226

interface DataSchemaReturn {

227

getSchemaForData(data: INodeExecutionData[]): Schema[];

228

inferSchema(value: unknown, path?: string): Schema;

229

validateDataAgainstSchema(data: unknown, schema: Schema[]): ValidationResult;

230

}

231

232

/**

233

* Pinned data management

234

*/

235

function usePinnedData(node: Ref<INodeUi>): PinnedDataReturn;

236

237

interface PinnedDataReturn {

238

pinnedData: ComputedRef<IDataObject[] | undefined>;

239

hasPinnedData: ComputedRef<boolean>;

240

setPinnedData(data: IDataObject[]): void;

241

removePinnedData(): void;

242

canPinData: ComputedRef<boolean>;

243

}

244

245

/**

246

* Expression editor functionality

247

*/

248

function useExpressionEditor(): ExpressionEditorReturn;

249

250

interface ExpressionEditorReturn {

251

segments: Ref<Segment[]>;

252

selection: Ref<Range>;

253

insertText(text: string): void;

254

insertExpression(expression: string): void;

255

getValue(): string;

256

setValue(value: string): void;

257

}

258

```

259

260

### Utility Composables

261

262

General utility composables for common functionality.

263

264

```typescript { .api }

265

/**

266

* Debounced reactive values

267

*/

268

function useDebounce<T>(value: Ref<T>, delay: number): {

269

debouncedValue: Ref<T>;

270

flush(): void;

271

cancel(): void;

272

};

273

274

/**

275

* Document title management

276

*/

277

function useDocumentTitle(): DocumentTitleReturn;

278

279

interface DocumentTitleReturn {

280

title: Ref<string>;

281

setTitle(newTitle: string): void;

282

resetTitle(): void;

283

}

284

285

/**

286

* Local storage with reactivity

287

*/

288

function useN8nLocalStorage<T>(

289

key: string,

290

defaultValue: T

291

): [Ref<T>, (value: T) => void];

292

293

/**

294

* Message handling

295

*/

296

function useMessage(): MessageReturn;

297

298

interface MessageReturn {

299

confirm(config: MessageBoxConfig): Promise<boolean>;

300

alert(config: MessageBoxConfig): Promise<void>;

301

prompt(config: MessageBoxConfig): Promise<string>;

302

}

303

304

/**

305

* External hooks integration

306

*/

307

function useExternalHooks(): ExternalHooksReturn;

308

309

interface ExternalHooksReturn {

310

run(hookName: string, ...args: any[]): Promise<void>;

311

runWithReturn<T>(hookName: string, ...args: any[]): Promise<T>;

312

}

313

```

314

315

## Usage Examples

316

317

**Canvas Node Composable:**

318

319

```vue

320

<script setup lang="ts">

321

import { useCanvasNode } from '@/composables/useCanvasNode';

322

323

// Access node data within canvas node component

324

const {

325

node,

326

name,

327

label,

328

inputs,

329

outputs,

330

isSelected,

331

hasIssues,

332

executionRunning

333

} = useCanvasNode();

334

335

// Reactive node properties

336

watchEffect(() => {

337

if (hasIssues.value) {

338

console.warn(`Node ${name.value} has issues`);

339

}

340

});

341

</script>

342

```

343

344

**Keyboard Bindings:**

345

346

```typescript

347

import { useKeybindings } from '@/composables/useKeybindings';

348

349

// Define keyboard shortcuts

350

const keyMap = {

351

'ctrl+s': () => saveWorkflow(),

352

'ctrl+z': () => undo(),

353

'ctrl+y': () => redo(),

354

'delete': () => deleteSelectedNodes(),

355

'ctrl+c': () => copyNodes(),

356

'ctrl+v': () => pasteNodes(),

357

'escape': () => deselectAll()

358

};

359

360

// Apply keybindings with options

361

useKeybindings(keyMap, {

362

disabled: computed(() => isModalOpen.value),

363

preventDefault: true

364

});

365

```

366

367

**Toast Notifications:**

368

369

```typescript

370

import { useToast } from '@/composables/useToast';

371

372

const toast = useToast();

373

374

// Show different types of notifications

375

const handleSuccess = () => {

376

toast.showSuccess('Workflow saved successfully!');

377

};

378

379

const handleError = (error: Error) => {

380

toast.showError(error, 'Failed to save workflow');

381

};

382

383

const handleCustomMessage = () => {

384

toast.showMessage({

385

message: 'Custom notification',

386

type: 'info',

387

duration: 5000,

388

showClose: true

389

});

390

};

391

```

392

393

**Data Schema Usage:**

394

395

```typescript

396

import { useDataSchema } from '@/composables/useDataSchema';

397

398

const { getSchemaForData, inferSchema } = useDataSchema();

399

400

// Infer schema from execution data

401

const executionData = [

402

{ json: { id: 1, name: 'John', active: true } },

403

{ json: { id: 2, name: 'Jane', active: false } }

404

];

405

406

const schema = getSchemaForData(executionData);

407

console.log(schema); // Inferred schema structure

408

```

409

410

## Types

411

412

```typescript { .api }

413

interface Segment {

414

kind: SegmentKind;

415

content: string;

416

from: number;

417

to: number;

418

}

419

420

enum SegmentKind {

421

Text = 'text',

422

Expression = 'expression',

423

Resolvable = 'resolvable'

424

}

425

426

interface Range {

427

from: number;

428

to: number;

429

}

430

431

interface Schema {

432

type: SchemaType;

433

key?: string;

434

value: string | Schema[];

435

path: string;

436

}

437

438

type SchemaType =

439

| 'string'

440

| 'number'

441

| 'boolean'

442

| 'array'

443

| 'object'

444

| 'null'

445

| 'undefined';

446

447

interface ValidationResult {

448

isValid: boolean;

449

errors: string[];

450

}

451

452

interface NotificationOptions {

453

message: string;

454

title?: string;

455

type?: 'success' | 'warning' | 'info' | 'error';

456

duration?: number;

457

showClose?: boolean;

458

offset?: number;

459

onClose?: () => void;

460

}

461

462

interface MessageBoxConfig {

463

title?: string;

464

message: string;

465

type?: 'success' | 'warning' | 'info' | 'error';

466

confirmButtonText?: string;

467

cancelButtonText?: string;

468

showCancelButton?: boolean;

469

dangerouslyUseHTMLString?: boolean;

470

}

471

472

type MaybeRefOrGetter<T> = T | Ref<T> | (() => T);

473

```