[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [local‑first/Protocol](https://evolu.dev/docs/api-reference/common/local-first/Protocol) › ProtocolMessageBuffer

Defined in: [packages/common/src/local-first/Protocol.ts:774](https://github.com/evoluhq/evolu/blob/113517df8a8da4e4eed41363077878e657b22fca/packages/common/src/local-first/Protocol.ts#L774)

Mutable builder for constructing [ProtocolMessage](https://evolu.dev/docs/api-reference/common/local-first/Protocol/type-aliases/ProtocolMessage) respecting size
limits.

A frame never exceeds `totalMaxSize`. Make ordinary writes inside `tryWrite`,
which keeps them only if the frame can still be closed. A write outside a
trial is a closing write: `addMessage` and `addRange` assert that the frame
fits `totalMaxSize`.

The builder references each change, which `unwrap` copies into the frame it
returns, so a change must not be modified while the builder is in use.
`unwrap` leaves the builder unchanged, so it can be called again.

## Properties

<a id="addmessage"></a>

### addMessage

```ts
readonly addMessage: (message: EncryptedCrdtMessage) => void;
```

Defined in: [packages/common/src/local-first/Protocol.ts:775](https://github.com/evoluhq/evolu/blob/113517df8a8da4e4eed41363077878e657b22fca/packages/common/src/local-first/Protocol.ts#L775)

<a id="addrange"></a>

### addRange

```ts
readonly addRange: (range:
  | SkipRange
  | FingerprintRange
  | TimestampsRangeWithTimestampsBuffer) => void;
```

Defined in: [packages/common/src/local-first/Protocol.ts:777](https://github.com/evoluhq/evolu/blob/113517df8a8da4e4eed41363077878e657b22fca/packages/common/src/local-first/Protocol.ts#L777)

<a id="getsize"></a>

### getSize

```ts
readonly getSize: () => number & Brand<"NonNaN"> & Brand<"Finite"> & Brand<"Int"> & Brand<"NonNegative"> & Brand<"Positive">;
```

Defined in: [packages/common/src/local-first/Protocol.ts:801](https://github.com/evoluhq/evolu/blob/113517df8a8da4e4eed41363077878e657b22fca/packages/common/src/local-first/Protocol.ts#L801)

Returns the exact encoded size of the frame.

<a id="trywrite"></a>

### tryWrite

```ts
readonly tryWrite: (write: () => void, reserve?: number & Brand<"NonNaN"> & Brand<"Finite"> & Brand<"Int"> & Brand<"NonNegative">) => boolean;
```

Defined in: [packages/common/src/local-first/Protocol.ts:796](https://github.com/evoluhq/evolu/blob/113517df8a8da4e4eed41363077878e657b22fca/packages/common/src/local-first/Protocol.ts#L796)

Runs `write` and keeps what it wrote only if the frame can still be closed,
returning whether it was kept.

The frame can be closed when its exact size plus the bytes needed to append
one Fingerprint range with [InfiniteUpperBound](https://evolu.dev/docs/api-reference/common/local-first/Storage/variables/InfiniteUpperBound) plus `reserve` is at
most `totalMaxSize`, and its ranges section plus the same bytes is at most
`rangesMaxSize`. Nothing is needed to close a broadcast, which holds no
ranges, or a frame whose last range has InfiniteUpperBound. Use `reserve`
for bytes the caller adds later, such as a range it is still collecting.

When the frame cannot be closed, or `write` throws, everything `write`
wrote is undone, so the frame is as if `write` never ran. Inside `write`,
`addMessage` and `addRange` do not assert the size limit.

<a id="unwrap"></a>

### unwrap

```ts
readonly unwrap: () => ProtocolMessage;
```

Defined in: [packages/common/src/local-first/Protocol.ts:798](https://github.com/evoluhq/evolu/blob/113517df8a8da4e4eed41363077878e657b22fca/packages/common/src/local-first/Protocol.ts#L798)