or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

common-nodes.mdfunction-nodes.mdindex.mdnetwork-nodes.mdparser-nodes.mdsequence-nodes.mdstorage-nodes.md

sequence-nodes.mddocs/

0

# Sequence Nodes

1

2

Sequence nodes provide message flow control and manipulation capabilities for handling arrays, message streams, and batch processing. These nodes enable complex data aggregation, splitting, and ordering operations within Node-RED flows.

3

4

## Capabilities

5

6

### Split Node

7

8

Split messages into sequences based on arrays, objects, or string delimiters. Creates a sequence of individual messages from composite data.

9

10

```javascript { .api }

11

/**

12

* Split node for breaking messages into sequences

13

* Registers as node type: "split"

14

*/

15

function SplitNode(config) {

16

RED.nodes.createNode(this, config);

17

18

// Configuration properties:

19

// config.splt - Split character/delimiter (for strings)

20

// config.spltType - Split type: "str", "len", "stream"

21

// config.arraySplt - Array split mode

22

// config.arraySpltType - Array split type

23

// config.stream - Stream mode for large objects

24

// config.addname - Add property name for object splits

25

}

26

```

27

28

**Usage Examples:**

29

30

```javascript

31

// Split array into individual messages

32

// Input: { payload: [1, 2, 3, 4, 5] }

33

// Output: { payload: 1, parts: {index: 0, count: 5, id: "abc"} }

34

// { payload: 2, parts: {index: 1, count: 5, id: "abc"} }

35

// ... etc

36

37

// Split string by delimiter

38

{

39

"splt": ",",

40

"spltType": "str"

41

}

42

// Input: { payload: "red,green,blue" }

43

// Output: { payload: "red", parts: {index: 0, count: 3, id: "def"} }

44

// { payload: "green", parts: {index: 1, count: 3, id: "def"} }

45

// { payload: "blue", parts: {index: 2, count: 3, id: "def"} }

46

47

// Split object into key-value pairs

48

{

49

"arraySplt": true,

50

"addname": true

51

}

52

// Input: { payload: {name: "John", age: 30, city: "NYC"} }

53

// Output: { payload: "John", topic: "name", parts: {...} }

54

// { payload: 30, topic: "age", parts: {...} }

55

// { payload: "NYC", topic: "city", parts: {...} }

56

```

57

58

### Join Node

59

60

Combine message sequences back into arrays, objects, or concatenated strings. Supports automatic and manual join modes.

61

62

```javascript { .api }

63

/**

64

* Join node for combining message sequences

65

* Registers as node type: "join"

66

*/

67

function JoinNode(config) {

68

RED.nodes.createNode(this, config);

69

70

// Configuration properties:

71

// config.mode - Join mode: "auto", "custom", "reduce"

72

// config.build - Build type: "array", "object", "string", "merged"

73

// config.property - Property to join (default: "payload")

74

// config.propertyType - Property type: "msg", "full"

75

// config.key - Key property for object building

76

// config.joiner - String joiner character

77

// config.joinerType - Joiner type

78

// config.accumulate - Accumulate results

79

// config.timeout - Join timeout in seconds

80

// config.count - Expected message count (manual mode)

81

}

82

```

83

84

**Usage Examples:**

85

86

```javascript

87

// Auto-join split array back together

88

{

89

"mode": "auto",

90

"build": "array"

91

}

92

// Input: Sequence of messages with parts.index/count/id

93

// Output: { payload: [1, 2, 3, 4, 5] }

94

95

// Join messages into object using topic as key

96

{

97

"mode": "custom",

98

"build": "object",

99

"key": "topic",

100

"count": "3"

101

}

102

// Input: { payload: "John", topic: "name" }

103

// { payload: 30, topic: "age" }

104

// { payload: "NYC", topic: "city" }

105

// Output: { payload: {name: "John", age: 30, city: "NYC"} }

106

107

// Join messages into string

108

{

109

"mode": "custom",

110

"build": "string",

111

"joiner": ", ",

112

"count": "3"

113

}

114

// Input: { payload: "red" }, { payload: "green" }, { payload: "blue" }

115

// Output: { payload: "red, green, blue" }

116

117

// Reduce mode for calculations

118

{

119

"mode": "reduce",

120

"build": "merged",

121

"reduceRight": false,

122

"reduceExp": "$A + payload",

123

"reduceInit": "0",

124

"reduceInitType": "num"

125

}

126

```

127

128

### Sort Node

129

130

Sort message sequences by specified properties with configurable sort order.

131

132

```javascript { .api }

133

/**

134

* Sort node for ordering message sequences

135

* Registers as node type: "sort"

136

*/

137

function SortNode(config) {

138

RED.nodes.createNode(this, config);

139

140

// Configuration properties:

141

// config.target - Property to sort by (default: "payload")

142

// config.targetType - Target type: "msg", "seq"

143

// config.msgKey - Message key for sorting

144

// config.msgKeyType - Key type: "elem", "jsonata"

145

// config.seqKey - Sequence key for sorting

146

// config.seqKeyType - Sequence key type

147

// config.order - Sort order: "ascending", "descending"

148

}

149

```

150

151

**Usage Examples:**

152

153

```javascript

154

// Sort by payload value (ascending)

155

{

156

"target": "payload",

157

"order": "ascending"

158

}

159

// Input: { payload: 3, parts: {...} }

160

// { payload: 1, parts: {...} }

161

// { payload: 2, parts: {...} }

162

// Output: { payload: 1, parts: {...} }

163

// { payload: 2, parts: {...} }

164

// { payload: 3, parts: {...} }

165

166

// Sort objects by property (descending)

167

{

168

"target": "payload",

169

"msgKey": "age",

170

"msgKeyType": "elem",

171

"order": "descending"

172

}

173

// Input: { payload: {name: "John", age: 30} }

174

// { payload: {name: "Jane", age: 25} }

175

// { payload: {name: "Bob", age: 35} }

176

// Output: { payload: {name: "Bob", age: 35} }

177

// { payload: {name: "John", age: 30} }

178

// { payload: {name: "Jane", age: 25} }

179

180

// Sort using JSONata expression

181

{

182

"msgKey": "payload.timestamp",

183

"msgKeyType": "jsonata",

184

"order": "ascending"

185

}

186

```

187

188

### Batch Node

189

190

Group messages into batches based on count, time intervals, or other criteria.

191

192

```javascript { .api }

193

/**

194

* Batch node for grouping messages

195

* Registers as node type: "batch"

196

*/

197

function BatchNode(config) {

198

RED.nodes.createNode(this, config);

199

200

// Configuration properties:

201

// config.mode - Batch mode: "count", "interval"

202

// config.count - Messages per batch (count mode)

203

// config.overlap - Overlap count for sliding window

204

// config.interval - Time interval in seconds (interval mode)

205

// config.allowEmptySequence - Allow empty batches

206

// config.topics - Topic grouping

207

}

208

```

209

210

**Usage Examples:**

211

212

```javascript

213

// Batch by message count

214

{

215

"mode": "count",

216

"count": "3",

217

"overlap": "0"

218

}

219

// Input: 6 individual messages

220

// Output: 2 batches of 3 messages each

221

222

// Sliding window batch

223

{

224

"mode": "count",

225

"count": "3",

226

"overlap": "1"

227

}

228

// Creates overlapping batches: [1,2,3], [2,3,4], [3,4,5], etc.

229

230

// Time-based batching

231

{

232

"mode": "interval",

233

"interval": "5"

234

}

235

// Collects messages for 5 seconds, then outputs batch

236

237

// Topic-based grouping

238

{

239

"mode": "count",

240

"count": "2",

241

"topics": true

242

}

243

// Groups messages by topic, batching within each topic

244

```

245

246

## Message Parts Structure

247

248

Sequence nodes use a standard `parts` property to track message sequences:

249

250

```javascript { .api }

251

// Message parts structure for sequence tracking

252

interface MessageParts {

253

id: string; // Unique sequence identifier

254

index: number; // Position in sequence (0-based)

255

count: number; // Total messages in sequence

256

type?: string; // Sequence type: "array", "object", "string"

257

ch?: string; // Character used for string splits

258

key?: string; // Object key (for object sequences)

259

len?: number; // Length information

260

}

261

262

// Example message with parts

263

interface SequenceMessage {

264

payload: any;

265

parts: MessageParts;

266

topic?: string; // May contain key for object sequences

267

[key: string]: any;

268

}

269

```

270

271

## Processing Patterns

272

273

Sequence nodes implement consistent patterns for handling message flows:

274

275

```javascript { .api }

276

// Standard sequence processing pattern

277

this.on("input", function(msg, send, done) {

278

try {

279

if (msg.hasOwnProperty("parts")) {

280

// Handle sequenced message

281

processSequencedMessage(msg);

282

} else {

283

// Handle standalone message

284

processStandaloneMessage(msg);

285

}

286

287

// Check if sequence is complete

288

if (isSequenceComplete()) {

289

var result = buildResult();

290

send(result);

291

}

292

293

done();

294

} catch (error) {

295

done(error);

296

}

297

});

298

299

// Sequence completion detection

300

function isSequenceComplete() {

301

// Check if all expected messages received

302

return receivedCount >= expectedCount;

303

}

304

```

305

306

## Advanced Features

307

308

### Reduce Operations

309

310

Join node supports reduce operations for calculations across sequences:

311

312

```javascript { .api }

313

// Reduce configuration for calculations

314

{

315

"mode": "reduce",

316

"build": "merged",

317

"reduceRight": false,

318

"reduceExp": "$A + payload.value", // JSONata expression

319

"reduceInit": "0", // Initial accumulator value

320

"reduceInitType": "num"

321

}

322

323

// Example reduce operations:

324

// Sum: "$A + payload"

325

// Product: "$A * payload"

326

// Max: "payload > $A ? payload : $A"

327

// Concatenate: "$A & payload"

328

// Count: "$A + 1"

329

```

330

331

### Timeout Handling

332

333

Join node supports timeouts for incomplete sequences:

334

335

```javascript { .api }

336

// Timeout configuration

337

{

338

"timeout": "30", // 30 second timeout

339

"build": "array",

340

"mode": "custom"

341

}

342

343

// Behavior on timeout:

344

// - Sends partial results if any messages received

345

// - Clears internal sequence state

346

// - Continues processing new sequences

347

```

348

349

### Topic-based Grouping

350

351

Batch node can group messages by topic for parallel processing:

352

353

```javascript { .api }

354

// Topic grouping configuration

355

{

356

"mode": "count",

357

"count": "5",

358

"topics": true

359

}

360

361

// Creates separate batches per topic:

362

// Topic "sensor1": [msg1, msg2, msg3, msg4, msg5]

363

// Topic "sensor2": [msg1, msg2, msg3, msg4, msg5]

364

// Each topic maintains independent batch state

365

```

366

367

## Error Handling

368

369

Sequence nodes handle various error conditions:

370

371

```javascript { .api }

372

// Common error scenarios:

373

374

// Missing parts property (join/sort nodes)

375

// Recovery: Treat as single-message sequence

376

377

// Sequence timeout (join node)

378

// Recovery: Send partial results, clear state

379

380

// Invalid sort key (sort node)

381

// Recovery: Skip sorting, pass messages through

382

383

// Memory limits (large sequences)

384

// Recovery: Implement backpressure, limit sequence size

385

```