or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

binary-io.mdcli-tools.mdcode-generation.mdindex.mdproto-loading.mdreflection.mdrpc-services.mdserialization.md

serialization.mddocs/

0

# Message Serialization

1

2

High-performance binary serialization and deserialization with full type safety, validation, and conversion capabilities for protobuf messages.

3

4

## Capabilities

5

6

### Message Class

7

8

Base message class providing static methods for all serialization operations and instance methods for message manipulation.

9

10

```javascript { .api }

11

class Message<T extends object = object> {

12

/**

13

* Message type reference

14

*/

15

$type: Type;

16

17

/**

18

* Creates message instance from properties

19

* @param properties - Message properties

20

* @returns Message instance

21

*/

22

static create<T extends Message<T>>(this: Constructor<T>, properties?: { [k: string]: any }): T;

23

24

/**

25

* Encodes message to writer

26

* @param message - Message instance or plain object

27

* @param writer - Writer to encode to, creates new if omitted

28

* @returns Writer with encoded data

29

*/

30

static encode<T extends Message<T>>(this: Constructor<T>, message: T | { [k: string]: any }, writer?: Writer): Writer;

31

32

/**

33

* Encodes message with length delimiter

34

* @param message - Message instance or plain object

35

* @param writer - Writer to encode to, creates new if omitted

36

* @returns Writer with encoded data

37

*/

38

static encodeDelimited<T extends Message<T>>(this: Constructor<T>, message: T | { [k: string]: any }, writer?: Writer): Writer;

39

40

/**

41

* Decodes message from reader or buffer

42

* @param reader - Reader or buffer to decode from

43

* @param length - Message length if known

44

* @returns Decoded message instance

45

*/

46

static decode<T extends Message<T>>(this: Constructor<T>, reader: Reader | Uint8Array, length?: number): T;

47

48

/**

49

* Decodes length-delimited message

50

* @param reader - Reader or buffer to decode from

51

* @returns Decoded message instance

52

*/

53

static decodeDelimited<T extends Message<T>>(this: Constructor<T>, reader: Reader | Uint8Array): T;

54

55

/**

56

* Verifies message properties

57

* @param message - Message properties to verify

58

* @returns Error message or null if valid

59

*/

60

static verify(message: { [k: string]: any }): string | null;

61

62

/**

63

* Creates message from plain object

64

* @param object - Plain object to convert

65

* @returns Message instance

66

*/

67

static fromObject<T extends Message<T>>(this: Constructor<T>, object: { [k: string]: any }): T;

68

69

/**

70

* Converts message to plain object

71

* @param message - Message instance to convert

72

* @param options - Conversion options

73

* @returns Plain object representation

74

*/

75

static toObject<T extends Message<T>>(message: T, options?: IConversionOptions): { [k: string]: any };

76

77

/**

78

* Converts message to JSON representation

79

* @returns JSON object

80

*/

81

toJSON(): { [k: string]: any };

82

83

/**

84

* Checks if message equals another message

85

* @param message - Message to compare with

86

* @returns True if messages are equal

87

*/

88

equals(message: Message): boolean;

89

}

90

```

91

92

**Usage Examples:**

93

94

```javascript

95

const protobuf = require("protobufjs");

96

97

// Load schema and get message type

98

protobuf.load("schema.proto", function(err, root) {

99

const User = root.lookupType("User");

100

101

// Create message

102

const user = User.create({

103

id: 123,

104

name: "John Doe",

105

email: "john@example.com"

106

});

107

108

// Encode to binary

109

const buffer = User.encode(user).finish();

110

console.log("Encoded size:", buffer.length);

111

112

// Decode from binary

113

const decoded = User.decode(buffer);

114

console.log("Decoded:", decoded);

115

116

// Verify message structure

117

const errorMsg = User.verify({

118

id: "invalid", // Should be number

119

name: "Valid Name"

120

});

121

if (errorMsg) console.log("Validation error:", errorMsg);

122

});

123

```

124

125

### Type-Based Operations

126

127

Operations available on Type instances for message manipulation.

128

129

```javascript { .api }

130

class Type extends Namespace {

131

/**

132

* Creates message instance with type validation

133

* @param properties - Message properties

134

* @returns Message instance

135

*/

136

create(properties?: { [k: string]: any }): Message;

137

138

/**

139

* Encodes message with type information

140

* @param message - Message to encode

141

* @param writer - Optional writer

142

* @returns Writer with encoded data

143

*/

144

encode(message: Message | { [k: string]: any }, writer?: Writer): Writer;

145

146

/**

147

* Encodes message with length delimiter

148

* @param message - Message to encode

149

* @param writer - Optional writer

150

* @returns Writer with encoded data

151

*/

152

encodeDelimited(message: Message | { [k: string]: any }, writer?: Writer): Writer;

153

154

/**

155

* Decodes message using type schema

156

* @param reader - Reader or buffer

157

* @param length - Optional message length

158

* @returns Decoded message

159

*/

160

decode(reader: Reader | Uint8Array, length?: number): Message;

161

162

/**

163

* Decodes length-delimited message

164

* @param reader - Reader or buffer

165

* @returns Decoded message

166

*/

167

decodeDelimited(reader: Reader | Uint8Array): Message;

168

169

/**

170

* Verifies message against type schema

171

* @param message - Message to verify

172

* @returns Error message or null

173

*/

174

verify(message: { [k: string]: any }): string | null;

175

176

/**

177

* Creates message from plain object with type conversion

178

* @param object - Plain object

179

* @returns Message instance

180

*/

181

fromObject(object: { [k: string]: any }): Message;

182

183

/**

184

* Converts message to plain object with type information

185

* @param message - Message to convert

186

* @param options - Conversion options

187

* @returns Plain object

188

*/

189

toObject(message: Message, options?: IConversionOptions): { [k: string]: any };

190

}

191

```

192

193

**Usage Examples:**

194

195

```javascript

196

// Using Type methods directly

197

const MessageType = root.lookupType("package.Message");

198

199

// Create and encode

200

const message = MessageType.create({ field1: "value", field2: 42 });

201

const encoded = MessageType.encode(message).finish();

202

203

// Decode and verify

204

const decoded = MessageType.decode(encoded);

205

const valid = MessageType.verify(decoded);

206

if (valid === null) {

207

console.log("Message is valid");

208

}

209

210

// Object conversion

211

const plainObject = MessageType.toObject(message, {

212

longs: String,

213

enums: String,

214

bytes: String

215

});

216

```

217

218

### Conversion Options

219

220

Configuration options for controlling serialization behavior and data type representation.

221

222

```javascript { .api }

223

interface IConversionOptions {

224

/**

225

* Long number representation

226

* - String: Convert to string representation

227

* - Number: Convert to JavaScript number (may lose precision)

228

* - Long: Keep as Long object

229

*/

230

longs?: typeof String | typeof Number | typeof Long;

231

232

/**

233

* Enum value representation

234

* - String: Use enum names

235

* - Number: Use enum numeric values

236

*/

237

enums?: typeof String | typeof Number;

238

239

/**

240

* Byte array representation

241

* - Array: Convert to number array

242

* - String: Convert to base64 string

243

* - Uint8Array: Keep as Uint8Array

244

*/

245

bytes?: typeof Array | typeof String | typeof Uint8Array;

246

247

/**

248

* Whether to include default values

249

*/

250

defaults?: boolean;

251

252

/**

253

* Whether to include empty arrays

254

*/

255

arrays?: boolean;

256

257

/**

258

* Whether to include empty objects

259

*/

260

objects?: boolean;

261

262

/**

263

* Whether to include oneof properties that aren't set

264

*/

265

oneofs?: boolean;

266

}

267

```

268

269

**Usage Examples:**

270

271

```javascript

272

const message = MessageType.create({

273

id: Long.fromNumber(123456789012345),

274

status: StatusEnum.values.ACTIVE,

275

data: new Uint8Array([1, 2, 3, 4])

276

});

277

278

// Convert with different options

279

const jsonFriendly = MessageType.toObject(message, {

280

longs: String, // "123456789012345"

281

enums: String, // "ACTIVE"

282

bytes: String, // base64 encoded

283

defaults: true // include default values

284

});

285

286

const numeric = MessageType.toObject(message, {

287

longs: Number, // 123456789012345 (may lose precision)

288

enums: Number, // 1

289

bytes: Array // [1, 2, 3, 4]

290

});

291

```

292

293

### Validation

294

295

Message validation capabilities for ensuring data integrity and type safety.

296

297

```javascript { .api }

298

/**

299

* Validates message properties against schema

300

* @param message - Message properties to validate

301

* @returns Error message string or null if valid

302

*/

303

function verify(message: { [k: string]: any }): string | null;

304

305

// Validation error types

306

interface ValidationErrors {

307

missingField: string; // "missing required field"

308

invalidType: string; // "invalid type for field"

309

outOfRange: string; // "value out of range"

310

invalidEnum: string; // "invalid enum value"

311

invalidOneOf: string; // "multiple oneof fields set"

312

}

313

```

314

315

**Usage Examples:**

316

317

```javascript

318

// Validate before encoding

319

const messageData = {

320

id: "not-a-number", // Invalid type

321

name: "", // Empty string

322

age: -5 // Invalid value

323

};

324

325

const error = MessageType.verify(messageData);

326

if (error) {

327

console.log("Validation failed:", error);

328

// Handle validation error

329

} else {

330

// Safe to create and encode

331

const message = MessageType.create(messageData);

332

const encoded = MessageType.encode(message).finish();

333

}

334

335

// Validate after decoding

336

const decoded = MessageType.decode(someBuffer);

337

const valid = MessageType.verify(decoded);

338

if (valid !== null) {

339

console.warn("Decoded message validation warning:", valid);

340

}

341

```

342

343

### Binary Format Operations

344

345

Low-level binary format operations for custom serialization needs.

346

347

```javascript { .api }

348

/**

349

* Finishes writer operations and returns encoded buffer

350

* @returns Encoded binary data

351

*/

352

Writer.prototype.finish(): Uint8Array;

353

354

/**

355

* Gets current writer length

356

* @returns Number of bytes written

357

*/

358

Writer.prototype.len: number;

359

360

/**

361

* Creates reader from binary data

362

* @param buffer - Binary data to read

363

* @returns Reader instance

364

*/

365

Reader.create(buffer: Uint8Array): Reader;

366

367

/**

368

* Current reader position

369

*/

370

Reader.prototype.pos: number;

371

372

/**

373

* Total buffer length

374

*/

375

Reader.prototype.len: number;

376

```

377

378

**Usage Examples:**

379

380

```javascript

381

// Custom encoding with length tracking

382

const writer = protobuf.Writer.create();

383

const message1 = Type1.encode(data1, writer);

384

const pos1 = writer.len;

385

386

const message2 = Type2.encode(data2, writer);

387

const pos2 = writer.len;

388

389

const buffer = writer.finish();

390

console.log(`Total size: ${buffer.length}, Message1: ${pos1}, Message2: ${pos2 - pos1}`);

391

392

// Custom decoding with position tracking

393

const reader = protobuf.Reader.create(buffer);

394

const decoded1 = Type1.decode(reader, pos1);

395

const decoded2 = Type2.decode(reader);

396

console.log(`Reader position: ${reader.pos}/${reader.len}`);

397

```

398

399

### Error Handling

400

401

Common error conditions and handling patterns in serialization operations.

402

403

```javascript { .api }

404

interface SerializationError extends Error {

405

name: string; // Error type

406

message: string; // Error description

407

path?: string; // Field path that caused error

408

instance?: any; // Problematic value

409

}

410

411

// Common error types

412

interface ErrorTypes {

413

TypeError: "invalid type";

414

RangeError: "value out of range";

415

Error: "general serialization error";

416

}

417

```

418

419

**Usage Examples:**

420

421

```javascript

422

try {

423

// Encoding errors

424

const message = MessageType.create({

425

requiredField: null, // Missing required field

426

enumField: 999 // Invalid enum value

427

});

428

const encoded = MessageType.encode(message).finish();

429

} catch (err) {

430

console.error("Encoding error:", err.message);

431

if (err.path) console.error("Field path:", err.path);

432

}

433

434

try {

435

// Decoding errors

436

const corrupted = new Uint8Array([0xFF, 0xFF, 0xFF]);

437

const decoded = MessageType.decode(corrupted);

438

} catch (err) {

439

console.error("Decoding error:", err.message);

440

}

441

```

442

443

## Types

444

445

```javascript { .api }

446

interface Constructor<T> extends Function {

447

new (...args: any[]): T;

448

}

449

450

interface IConversionOptions {

451

longs?: typeof String | typeof Number | typeof Long;

452

enums?: typeof String | typeof Number;

453

bytes?: typeof Array | typeof String | typeof Uint8Array;

454

defaults?: boolean;

455

arrays?: boolean;

456

objects?: boolean;

457

oneofs?: boolean;

458

}

459

460

interface Long {

461

low: number;

462

high: number;

463

unsigned: boolean;

464

toNumber(): number;

465

toString(): string;

466

equals(other: Long): boolean;

467

static fromNumber(value: number): Long;

468

static fromString(value: string): Long;

469

}

470

```